2 # -*- coding: utf-8 -*-
5 'Ricardo Garcia Gonzalez',
13 'Philipp Hagemeister',
21 'Jaime Marquínez Ferrándiz',
25 'M. Yasoob Ullah Khalid',
33 'Steffan \'Ruirize\' James',
42 __license__
= 'Public Domain'
68 from .update
import update_self
69 from .FileDownloader
import (
72 from .extractor
import gen_extractors
73 from .version
import __version__
74 from .YoutubeDL
import YoutubeDL
75 from .PostProcessor
import (
79 FFmpegEmbedSubtitlePP
,
83 def parseOpts(overrideArguments
=None):
84 def _readOptions(filename_bytes
, default
=[]):
86 optionf
= open(filename_bytes
)
88 return default
# silently skip if file is not present
92 res
+= shlex
.split(l
, comments
=True)
97 def _format_option_string(option
):
98 ''' ('-o', '--option') -> -o, --format METAVAR'''
102 if option
._short
_opts
:
103 opts
.append(option
._short
_opts
[0])
104 if option
._long
_opts
:
105 opts
.append(option
._long
_opts
[0])
109 if option
.takes_value(): opts
.append(' %s' % option
.metavar
)
113 def _comma_separated_values_options_callback(option
, opt_str
, value
, parser
):
114 setattr(parser
.values
, option
.dest
, value
.split(','))
116 def _find_term_columns():
117 columns
= os
.environ
.get('COLUMNS', None)
122 sp
= subprocess
.Popen(['stty', 'size'], stdout
=subprocess
.PIPE
, stderr
=subprocess
.PIPE
)
123 out
,err
= sp
.communicate()
124 return int(out
.split()[1])
129 def _hide_login_info(opts
):
131 for private_opt
in ['-p', '--password', '-u', '--username', '--video-password']:
133 i
= opts
.index(private_opt
)
134 opts
[i
+1] = '<PRIVATE>'
140 max_help_position
= 80
142 # No need to wrap help messages if we're on a wide console
143 columns
= _find_term_columns()
144 if columns
: max_width
= columns
146 fmt
= optparse
.IndentedHelpFormatter(width
=max_width
, max_help_position
=max_help_position
)
147 fmt
.format_option_strings
= _format_option_string
150 'version' : __version__
,
152 'usage' : '%prog [options] url [url...]',
153 'conflict_handler' : 'resolve',
156 parser
= optparse
.OptionParser(**kw
)
159 general
= optparse
.OptionGroup(parser
, 'General Options')
160 selection
= optparse
.OptionGroup(parser
, 'Video Selection')
161 authentication
= optparse
.OptionGroup(parser
, 'Authentication Options')
162 video_format
= optparse
.OptionGroup(parser
, 'Video Format Options')
163 subtitles
= optparse
.OptionGroup(parser
, 'Subtitle Options')
164 downloader
= optparse
.OptionGroup(parser
, 'Download Options')
165 postproc
= optparse
.OptionGroup(parser
, 'Post-processing Options')
166 filesystem
= optparse
.OptionGroup(parser
, 'Filesystem Options')
167 verbosity
= optparse
.OptionGroup(parser
, 'Verbosity / Simulation Options')
169 general
.add_option('-h', '--help',
170 action
='help', help='print this help text and exit')
171 general
.add_option('-v', '--version',
172 action
='version', help='print program version and exit')
173 general
.add_option('-U', '--update',
174 action
='store_true', dest
='update_self', help='update this program to latest version. Make sure that you have sufficient permissions (run with sudo if needed)')
175 general
.add_option('-i', '--ignore-errors',
176 action
='store_true', dest
='ignoreerrors', help='continue on download errors, for example to to skip unavailable videos in a playlist', default
=False)
177 general
.add_option('--abort-on-error',
178 action
='store_false', dest
='ignoreerrors',
179 help='Abort downloading of further videos (in the playlist or the command line) if an error occurs')
180 general
.add_option('--dump-user-agent',
181 action
='store_true', dest
='dump_user_agent',
182 help='display the current browser identification', default
=False)
183 general
.add_option('--user-agent',
184 dest
='user_agent', help='specify a custom user agent', metavar
='UA')
185 general
.add_option('--referer',
186 dest
='referer', help='specify a custom referer, use if the video access is restricted to one domain',
187 metavar
='REF', default
=None)
188 general
.add_option('--list-extractors',
189 action
='store_true', dest
='list_extractors',
190 help='List all supported extractors and the URLs they would handle', default
=False)
191 general
.add_option('--extractor-descriptions',
192 action
='store_true', dest
='list_extractor_descriptions',
193 help='Output descriptions of all supported extractors', default
=False)
195 '--proxy', dest
='proxy', default
=None, metavar
='URL',
196 help='Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection')
197 general
.add_option('--no-check-certificate', action
='store_true', dest
='no_check_certificate', default
=False, help='Suppress HTTPS certificate validation.')
199 '--cache-dir', dest
='cachedir', default
=get_cachedir(), metavar
='DIR',
200 help='Location in the filesystem where youtube-dl can store downloaded information permanently. By default $XDG_CACHE_HOME/youtube-dl or ~/.cache/youtube-dl .')
202 '--no-cache-dir', action
='store_const', const
=None, dest
='cachedir',
203 help='Disable filesystem caching')
205 '--socket-timeout', dest
='socket_timeout',
206 type=float, default
=None, help=optparse
.SUPPRESS_HELP
)
209 selection
.add_option('--playlist-start',
210 dest
='playliststart', metavar
='NUMBER', help='playlist video to start at (default is %default)', default
=1)
211 selection
.add_option('--playlist-end',
212 dest
='playlistend', metavar
='NUMBER', help='playlist video to end at (default is last)', default
=-1)
213 selection
.add_option('--match-title', dest
='matchtitle', metavar
='REGEX',help='download only matching titles (regex or caseless sub-string)')
214 selection
.add_option('--reject-title', dest
='rejecttitle', metavar
='REGEX',help='skip download for matching titles (regex or caseless sub-string)')
215 selection
.add_option('--max-downloads', metavar
='NUMBER',
216 dest
='max_downloads', type=int, default
=None,
217 help='Abort after downloading NUMBER files')
218 selection
.add_option('--min-filesize', metavar
='SIZE', dest
='min_filesize', help="Do not download any videos smaller than SIZE (e.g. 50k or 44.6m)", default
=None)
219 selection
.add_option('--max-filesize', metavar
='SIZE', dest
='max_filesize', help="Do not download any videos larger than SIZE (e.g. 50k or 44.6m)", default
=None)
220 selection
.add_option('--date', metavar
='DATE', dest
='date', help='download only videos uploaded in this date', default
=None)
221 selection
.add_option('--datebefore', metavar
='DATE', dest
='datebefore', help='download only videos uploaded before this date', default
=None)
222 selection
.add_option('--dateafter', metavar
='DATE', dest
='dateafter', help='download only videos uploaded after this date', default
=None)
223 selection
.add_option('--no-playlist', action
='store_true', dest
='noplaylist', help='download only the currently playing video', default
=False)
224 selection
.add_option('--age-limit', metavar
='YEARS', dest
='age_limit',
225 help='download only videos suitable for the given age',
226 default
=None, type=int)
227 selection
.add_option('--download-archive', metavar
='FILE',
228 dest
='download_archive',
229 help='Download only videos not listed in the archive file. Record the IDs of all downloaded videos in it.')
232 authentication
.add_option('-u', '--username',
233 dest
='username', metavar
='USERNAME', help='account username')
234 authentication
.add_option('-p', '--password',
235 dest
='password', metavar
='PASSWORD', help='account password')
236 authentication
.add_option('-n', '--netrc',
237 action
='store_true', dest
='usenetrc', help='use .netrc authentication data', default
=False)
238 authentication
.add_option('--video-password',
239 dest
='videopassword', metavar
='PASSWORD', help='video password (vimeo only)')
242 video_format
.add_option('-f', '--format',
243 action
='store', dest
='format', metavar
='FORMAT', default
='best',
244 help='video format code, specify the order of preference using slashes: "-f 22/17/18". "-f mp4" and "-f flv" are also supported')
245 video_format
.add_option('--all-formats',
246 action
='store_const', dest
='format', help='download all available video formats', const
='all')
247 video_format
.add_option('--prefer-free-formats',
248 action
='store_true', dest
='prefer_free_formats', default
=False, help='prefer free video formats unless a specific one is requested')
249 video_format
.add_option('--max-quality',
250 action
='store', dest
='format_limit', metavar
='FORMAT', help='highest quality format to download')
251 video_format
.add_option('-F', '--list-formats',
252 action
='store_true', dest
='listformats', help='list all available formats (currently youtube only)')
254 subtitles
.add_option('--write-sub', '--write-srt',
255 action
='store_true', dest
='writesubtitles',
256 help='write subtitle file', default
=False)
257 subtitles
.add_option('--write-auto-sub', '--write-automatic-sub',
258 action
='store_true', dest
='writeautomaticsub',
259 help='write automatic subtitle file (youtube only)', default
=False)
260 subtitles
.add_option('--all-subs',
261 action
='store_true', dest
='allsubtitles',
262 help='downloads all the available subtitles of the video', default
=False)
263 subtitles
.add_option('--list-subs',
264 action
='store_true', dest
='listsubtitles',
265 help='lists all available subtitles for the video', default
=False)
266 subtitles
.add_option('--sub-format',
267 action
='store', dest
='subtitlesformat', metavar
='FORMAT',
268 help='subtitle format (default=srt) ([sbv/vtt] youtube only)', default
='srt')
269 subtitles
.add_option('--sub-lang', '--sub-langs', '--srt-lang',
270 action
='callback', dest
='subtitleslangs', metavar
='LANGS', type='str',
271 default
=[], callback
=_comma_separated_values_options_callback
,
272 help='languages of the subtitles to download (optional) separated by commas, use IETF language tags like \'en,pt\'')
274 downloader
.add_option('-r', '--rate-limit',
275 dest
='ratelimit', metavar
='LIMIT', help='maximum download rate in bytes per second (e.g. 50K or 4.2M)')
276 downloader
.add_option('-R', '--retries',
277 dest
='retries', metavar
='RETRIES', help='number of retries (default is %default)', default
=10)
278 downloader
.add_option('--buffer-size',
279 dest
='buffersize', metavar
='SIZE', help='size of download buffer (e.g. 1024 or 16K) (default is %default)', default
="1024")
280 downloader
.add_option('--no-resize-buffer',
281 action
='store_true', dest
='noresizebuffer',
282 help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default
=False)
283 downloader
.add_option('--test', action
='store_true', dest
='test', default
=False, help=optparse
.SUPPRESS_HELP
)
285 verbosity
.add_option('-q', '--quiet',
286 action
='store_true', dest
='quiet', help='activates quiet mode', default
=False)
287 verbosity
.add_option('-s', '--simulate',
288 action
='store_true', dest
='simulate', help='do not download the video and do not write anything to disk', default
=False)
289 verbosity
.add_option('--skip-download',
290 action
='store_true', dest
='skip_download', help='do not download the video', default
=False)
291 verbosity
.add_option('-g', '--get-url',
292 action
='store_true', dest
='geturl', help='simulate, quiet but print URL', default
=False)
293 verbosity
.add_option('-e', '--get-title',
294 action
='store_true', dest
='gettitle', help='simulate, quiet but print title', default
=False)
295 verbosity
.add_option('--get-id',
296 action
='store_true', dest
='getid', help='simulate, quiet but print id', default
=False)
297 verbosity
.add_option('--get-thumbnail',
298 action
='store_true', dest
='getthumbnail',
299 help='simulate, quiet but print thumbnail URL', default
=False)
300 verbosity
.add_option('--get-description',
301 action
='store_true', dest
='getdescription',
302 help='simulate, quiet but print video description', default
=False)
303 verbosity
.add_option('--get-filename',
304 action
='store_true', dest
='getfilename',
305 help='simulate, quiet but print output filename', default
=False)
306 verbosity
.add_option('--get-format',
307 action
='store_true', dest
='getformat',
308 help='simulate, quiet but print output format', default
=False)
309 verbosity
.add_option('-j', '--dump-json',
310 action
='store_true', dest
='dumpjson',
311 help='simulate, quiet but print JSON information', default
=False)
312 verbosity
.add_option('--newline',
313 action
='store_true', dest
='progress_with_newline', help='output progress bar as new lines', default
=False)
314 verbosity
.add_option('--no-progress',
315 action
='store_true', dest
='noprogress', help='do not print progress bar', default
=False)
316 verbosity
.add_option('--console-title',
317 action
='store_true', dest
='consoletitle',
318 help='display progress in console titlebar', default
=False)
319 verbosity
.add_option('-v', '--verbose',
320 action
='store_true', dest
='verbose', help='print various debugging information', default
=False)
321 verbosity
.add_option('--dump-intermediate-pages',
322 action
='store_true', dest
='dump_intermediate_pages', default
=False,
323 help='print downloaded pages to debug problems(very verbose)')
324 verbosity
.add_option('--write-pages',
325 action
='store_true', dest
='write_pages', default
=False,
326 help='Write downloaded intermediary pages to files in the current directory to debug problems')
327 verbosity
.add_option('--youtube-print-sig-code',
328 action
='store_true', dest
='youtube_print_sig_code', default
=False,
329 help=optparse
.SUPPRESS_HELP
)
332 filesystem
.add_option('-t', '--title',
333 action
='store_true', dest
='usetitle', help='use title in file name (default)', default
=False)
334 filesystem
.add_option('--id',
335 action
='store_true', dest
='useid', help='use only video ID in file name', default
=False)
336 filesystem
.add_option('-l', '--literal',
337 action
='store_true', dest
='usetitle', help='[deprecated] alias of --title', default
=False)
338 filesystem
.add_option('-A', '--auto-number',
339 action
='store_true', dest
='autonumber',
340 help='number downloaded files starting from 00000', default
=False)
341 filesystem
.add_option('-o', '--output',
342 dest
='outtmpl', metavar
='TEMPLATE',
343 help=('output filename template. Use %(title)s to get the title, '
344 '%(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, '
345 '%(autonumber)s to get an automatically incremented number, '
346 '%(ext)s for the filename extension, '
347 '%(format)s for the format description (like "22 - 1280x720" or "HD"),'
348 '%(format_id)s for the unique id of the format (like Youtube\'s itags: "137"),'
349 '%(upload_date)s for the upload date (YYYYMMDD), '
350 '%(extractor)s for the provider (youtube, metacafe, etc), '
351 '%(id)s for the video id , %(playlist)s for the playlist the video is in, '
352 '%(playlist_index)s for the position in the playlist and %% for a literal percent. '
353 'Use - to output to stdout. Can also be used to download to a different directory, '
354 'for example with -o \'/my/downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s\' .'))
355 filesystem
.add_option('--autonumber-size',
356 dest
='autonumber_size', metavar
='NUMBER',
357 help='Specifies the number of digits in %(autonumber)s when it is present in output filename template or --auto-number option is given')
358 filesystem
.add_option('--restrict-filenames',
359 action
='store_true', dest
='restrictfilenames',
360 help='Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames', default
=False)
361 filesystem
.add_option('-a', '--batch-file',
362 dest
='batchfile', metavar
='FILE', help='file containing URLs to download (\'-\' for stdin)')
363 filesystem
.add_option('-w', '--no-overwrites',
364 action
='store_true', dest
='nooverwrites', help='do not overwrite files', default
=False)
365 filesystem
.add_option('-c', '--continue',
366 action
='store_true', dest
='continue_dl', help='force resume of partially downloaded files. By default, youtube-dl will resume downloads if possible.', default
=True)
367 filesystem
.add_option('--no-continue',
368 action
='store_false', dest
='continue_dl',
369 help='do not resume partially downloaded files (restart from beginning)')
370 filesystem
.add_option('--cookies',
371 dest
='cookiefile', metavar
='FILE', help='file to read cookies from and dump cookie jar in')
372 filesystem
.add_option('--no-part',
373 action
='store_true', dest
='nopart', help='do not use .part files', default
=False)
374 filesystem
.add_option('--no-mtime',
375 action
='store_false', dest
='updatetime',
376 help='do not use the Last-modified header to set the file modification time', default
=True)
377 filesystem
.add_option('--write-description',
378 action
='store_true', dest
='writedescription',
379 help='write video description to a .description file', default
=False)
380 filesystem
.add_option('--write-info-json',
381 action
='store_true', dest
='writeinfojson',
382 help='write video metadata to a .info.json file', default
=False)
383 filesystem
.add_option('--write-annotations',
384 action
='store_true', dest
='writeannotations',
385 help='write video annotations to a .annotation file', default
=False)
386 filesystem
.add_option('--write-thumbnail',
387 action
='store_true', dest
='writethumbnail',
388 help='write thumbnail image to disk', default
=False)
391 postproc
.add_option('-x', '--extract-audio', action
='store_true', dest
='extractaudio', default
=False,
392 help='convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe)')
393 postproc
.add_option('--audio-format', metavar
='FORMAT', dest
='audioformat', default
='best',
394 help='"best", "aac", "vorbis", "mp3", "m4a", "opus", or "wav"; best by default')
395 postproc
.add_option('--audio-quality', metavar
='QUALITY', dest
='audioquality', default
='5',
396 help='ffmpeg/avconv audio quality specification, insert a value between 0 (better) and 9 (worse) for VBR or a specific bitrate like 128K (default 5)')
397 postproc
.add_option('--recode-video', metavar
='FORMAT', dest
='recodevideo', default
=None,
398 help='Encode the video to another format if necessary (currently supported: mp4|flv|ogg|webm)')
399 postproc
.add_option('-k', '--keep-video', action
='store_true', dest
='keepvideo', default
=False,
400 help='keeps the video file on disk after the post-processing; the video is erased by default')
401 postproc
.add_option('--no-post-overwrites', action
='store_true', dest
='nopostoverwrites', default
=False,
402 help='do not overwrite post-processed files; the post-processed files are overwritten by default')
403 postproc
.add_option('--embed-subs', action
='store_true', dest
='embedsubtitles', default
=False,
404 help='embed subtitles in the video (only for mp4 videos)')
405 postproc
.add_option('--add-metadata', action
='store_true', dest
='addmetadata', default
=False,
406 help='add metadata to the files')
409 parser
.add_option_group(general
)
410 parser
.add_option_group(selection
)
411 parser
.add_option_group(downloader
)
412 parser
.add_option_group(filesystem
)
413 parser
.add_option_group(verbosity
)
414 parser
.add_option_group(video_format
)
415 parser
.add_option_group(subtitles
)
416 parser
.add_option_group(authentication
)
417 parser
.add_option_group(postproc
)
419 if overrideArguments
is not None:
420 opts
, args
= parser
.parse_args(overrideArguments
)
422 write_string(u
'[debug] Override config: ' + repr(overrideArguments
) + '\n')
424 systemConf
= _readOptions('/etc/youtube-dl.conf')
426 xdg_config_home
= os
.environ
.get('XDG_CONFIG_HOME')
428 userConfFile
= os
.path
.join(xdg_config_home
, 'youtube-dl', 'config')
429 if not os
.path
.isfile(userConfFile
):
430 userConfFile
= os
.path
.join(xdg_config_home
, 'youtube-dl.conf')
432 userConfFile
= os
.path
.join(os
.path
.expanduser('~'), '.config', 'youtube-dl', 'config')
433 if not os
.path
.isfile(userConfFile
):
434 userConfFile
= os
.path
.join(os
.path
.expanduser('~'), '.config', 'youtube-dl.conf')
435 userConf
= _readOptions(userConfFile
, None)
438 appdata_dir
= os
.environ
.get('appdata')
440 userConf
= _readOptions(
441 os
.path
.join(appdata_dir
, 'youtube-dl', 'config'),
444 userConf
= _readOptions(
445 os
.path
.join(appdata_dir
, 'youtube-dl', 'config.txt'),
449 userConf
= _readOptions(
450 os
.path
.join(os
.path
.expanduser('~'), 'youtube-dl.conf'),
453 userConf
= _readOptions(
454 os
.path
.join(os
.path
.expanduser('~'), 'youtube-dl.conf.txt'),
460 commandLineConf
= sys
.argv
[1:]
461 argv
= systemConf
+ userConf
+ commandLineConf
462 opts
, args
= parser
.parse_args(argv
)
464 write_string(u
'[debug] System config: ' + repr(_hide_login_info(systemConf
)) + '\n')
465 write_string(u
'[debug] User config: ' + repr(_hide_login_info(userConf
)) + '\n')
466 write_string(u
'[debug] Command-line args: ' + repr(_hide_login_info(commandLineConf
)) + '\n')
468 return parser
, opts
, args
470 def _real_main(argv
=None):
471 # Compatibility fixes for Windows
472 if sys
.platform
== 'win32':
473 # https://github.com/rg3/youtube-dl/issues/820
474 codecs
.register(lambda name
: codecs
.lookup('utf-8') if name
== 'cp65001' else None)
476 parser
, opts
, args
= parseOpts(argv
)
479 if opts
.user_agent
is not None:
480 std_headers
['User-Agent'] = opts
.user_agent
483 if opts
.referer
is not None:
484 std_headers
['Referer'] = opts
.referer
487 if opts
.dump_user_agent
:
488 compat_print(std_headers
['User-Agent'])
491 # Batch file verification
493 if opts
.batchfile
is not None:
495 if opts
.batchfile
== '-':
498 batchfd
= open(opts
.batchfile
, 'r')
499 batchurls
= batchfd
.readlines()
500 batchurls
= [x
.strip() for x
in batchurls
]
501 batchurls
= [x
for x
in batchurls
if len(x
) > 0 and not re
.search(r
'^[#/;]', x
)]
503 write_string(u
'[debug] Batch file urls: ' + repr(batchurls
) + u
'\n')
505 sys
.exit(u
'ERROR: batch file could not be read')
506 all_urls
= batchurls
+ args
507 all_urls
= [url
.strip() for url
in all_urls
]
509 extractors
= gen_extractors()
511 if opts
.list_extractors
:
512 for ie
in sorted(extractors
, key
=lambda ie
: ie
.IE_NAME
.lower()):
513 compat_print(ie
.IE_NAME
+ (' (CURRENTLY BROKEN)' if not ie
._WORKING
else ''))
514 matchedUrls
= [url
for url
in all_urls
if ie
.suitable(url
)]
515 all_urls
= [url
for url
in all_urls
if url
not in matchedUrls
]
516 for mu
in matchedUrls
:
517 compat_print(u
' ' + mu
)
519 if opts
.list_extractor_descriptions
:
520 for ie
in sorted(extractors
, key
=lambda ie
: ie
.IE_NAME
.lower()):
523 desc
= getattr(ie
, 'IE_DESC', ie
.IE_NAME
)
526 if hasattr(ie
, 'SEARCH_KEY'):
527 _SEARCHES
= (u
'cute kittens', u
'slithering pythons', u
'falling cat', u
'angry poodle', u
'purple fish', u
'running tortoise')
528 _COUNTS
= (u
'', u
'5', u
'10', u
'all')
529 desc
+= u
' (Example: "%s%s:%s" )' % (ie
.SEARCH_KEY
, random
.choice(_COUNTS
), random
.choice(_SEARCHES
))
534 # Conflicting, missing and erroneous options
535 if opts
.usenetrc
and (opts
.username
is not None or opts
.password
is not None):
536 parser
.error(u
'using .netrc conflicts with giving username/password')
537 if opts
.password
is not None and opts
.username
is None:
538 parser
.error(u
' account username missing\n')
539 if opts
.outtmpl
is not None and (opts
.usetitle
or opts
.autonumber
or opts
.useid
):
540 parser
.error(u
'using output template conflicts with using title, video ID or auto number')
541 if opts
.usetitle
and opts
.useid
:
542 parser
.error(u
'using title conflicts with using video ID')
543 if opts
.username
is not None and opts
.password
is None:
544 opts
.password
= getpass
.getpass(u
'Type account password and press return:')
545 if opts
.ratelimit
is not None:
546 numeric_limit
= FileDownloader
.parse_bytes(opts
.ratelimit
)
547 if numeric_limit
is None:
548 parser
.error(u
'invalid rate limit specified')
549 opts
.ratelimit
= numeric_limit
550 if opts
.min_filesize
is not None:
551 numeric_limit
= FileDownloader
.parse_bytes(opts
.min_filesize
)
552 if numeric_limit
is None:
553 parser
.error(u
'invalid min_filesize specified')
554 opts
.min_filesize
= numeric_limit
555 if opts
.max_filesize
is not None:
556 numeric_limit
= FileDownloader
.parse_bytes(opts
.max_filesize
)
557 if numeric_limit
is None:
558 parser
.error(u
'invalid max_filesize specified')
559 opts
.max_filesize
= numeric_limit
560 if opts
.retries
is not None:
562 opts
.retries
= int(opts
.retries
)
563 except (TypeError, ValueError):
564 parser
.error(u
'invalid retry count specified')
565 if opts
.buffersize
is not None:
566 numeric_buffersize
= FileDownloader
.parse_bytes(opts
.buffersize
)
567 if numeric_buffersize
is None:
568 parser
.error(u
'invalid buffer size specified')
569 opts
.buffersize
= numeric_buffersize
571 opts
.playliststart
= int(opts
.playliststart
)
572 if opts
.playliststart
<= 0:
573 raise ValueError(u
'Playlist start must be positive')
574 except (TypeError, ValueError):
575 parser
.error(u
'invalid playlist start number specified')
577 opts
.playlistend
= int(opts
.playlistend
)
578 if opts
.playlistend
!= -1 and (opts
.playlistend
<= 0 or opts
.playlistend
< opts
.playliststart
):
579 raise ValueError(u
'Playlist end must be greater than playlist start')
580 except (TypeError, ValueError):
581 parser
.error(u
'invalid playlist end number specified')
582 if opts
.extractaudio
:
583 if opts
.audioformat
not in ['best', 'aac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav']:
584 parser
.error(u
'invalid audio format specified')
585 if opts
.audioquality
:
586 opts
.audioquality
= opts
.audioquality
.strip('k').strip('K')
587 if not opts
.audioquality
.isdigit():
588 parser
.error(u
'invalid audio quality specified')
589 if opts
.recodevideo
is not None:
590 if opts
.recodevideo
not in ['mp4', 'flv', 'webm', 'ogg']:
591 parser
.error(u
'invalid video recode format specified')
592 if opts
.date
is not None:
593 date
= DateRange
.day(opts
.date
)
595 date
= DateRange(opts
.dateafter
, opts
.datebefore
)
597 # --all-sub automatically sets --write-sub if --write-auto-sub is not given
598 # this was the old behaviour if only --all-sub was given.
599 if opts
.allsubtitles
and (opts
.writeautomaticsub
== False):
600 opts
.writesubtitles
= True
602 if sys
.version_info
< (3,):
603 # In Python 2, sys.argv is a bytestring (also note http://bugs.python.org/issue2128 for Windows systems)
604 if opts
.outtmpl
is not None:
605 opts
.outtmpl
= opts
.outtmpl
.decode(preferredencoding())
606 outtmpl
=((opts
.outtmpl
is not None and opts
.outtmpl
)
607 or (opts
.format
== '-1' and opts
.usetitle
and u
'%(title)s-%(id)s-%(format)s.%(ext)s')
608 or (opts
.format
== '-1' and u
'%(id)s-%(format)s.%(ext)s')
609 or (opts
.usetitle
and opts
.autonumber
and u
'%(autonumber)s-%(title)s-%(id)s.%(ext)s')
610 or (opts
.usetitle
and u
'%(title)s-%(id)s.%(ext)s')
611 or (opts
.useid
and u
'%(id)s.%(ext)s')
612 or (opts
.autonumber
and u
'%(autonumber)s-%(id)s.%(ext)s')
613 or u
'%(title)s-%(id)s.%(ext)s')
614 if '%(ext)s' not in outtmpl
and opts
.extractaudio
:
615 parser
.error(u
'Cannot download a video and extract audio into the same'
616 u
' file! Use "%%(ext)s" instead of %r' %
617 determine_ext(outtmpl
, u
''))
620 'usenetrc': opts
.usenetrc
,
621 'username': opts
.username
,
622 'password': opts
.password
,
623 'videopassword': opts
.videopassword
,
624 'quiet': (opts
.quiet
or opts
.geturl
or opts
.gettitle
or opts
.getid
or opts
.getthumbnail
or opts
.getdescription
or opts
.getfilename
or opts
.getformat
or opts
.dumpjson
),
625 'forceurl': opts
.geturl
,
626 'forcetitle': opts
.gettitle
,
627 'forceid': opts
.getid
,
628 'forcethumbnail': opts
.getthumbnail
,
629 'forcedescription': opts
.getdescription
,
630 'forcefilename': opts
.getfilename
,
631 'forceformat': opts
.getformat
,
632 'forcejson': opts
.dumpjson
,
633 'simulate': opts
.simulate
,
634 'skip_download': (opts
.skip_download
or opts
.simulate
or opts
.geturl
or opts
.gettitle
or opts
.getid
or opts
.getthumbnail
or opts
.getdescription
or opts
.getfilename
or opts
.getformat
or opts
.dumpjson
),
635 'format': opts
.format
,
636 'format_limit': opts
.format_limit
,
637 'listformats': opts
.listformats
,
639 'autonumber_size': opts
.autonumber_size
,
640 'restrictfilenames': opts
.restrictfilenames
,
641 'ignoreerrors': opts
.ignoreerrors
,
642 'ratelimit': opts
.ratelimit
,
643 'nooverwrites': opts
.nooverwrites
,
644 'retries': opts
.retries
,
645 'buffersize': opts
.buffersize
,
646 'noresizebuffer': opts
.noresizebuffer
,
647 'continuedl': opts
.continue_dl
,
648 'noprogress': opts
.noprogress
,
649 'progress_with_newline': opts
.progress_with_newline
,
650 'playliststart': opts
.playliststart
,
651 'playlistend': opts
.playlistend
,
652 'noplaylist': opts
.noplaylist
,
653 'logtostderr': opts
.outtmpl
== '-',
654 'consoletitle': opts
.consoletitle
,
655 'nopart': opts
.nopart
,
656 'updatetime': opts
.updatetime
,
657 'writedescription': opts
.writedescription
,
658 'writeannotations': opts
.writeannotations
,
659 'writeinfojson': opts
.writeinfojson
,
660 'writethumbnail': opts
.writethumbnail
,
661 'writesubtitles': opts
.writesubtitles
,
662 'writeautomaticsub': opts
.writeautomaticsub
,
663 'allsubtitles': opts
.allsubtitles
,
664 'listsubtitles': opts
.listsubtitles
,
665 'subtitlesformat': opts
.subtitlesformat
,
666 'subtitleslangs': opts
.subtitleslangs
,
667 'matchtitle': decodeOption(opts
.matchtitle
),
668 'rejecttitle': decodeOption(opts
.rejecttitle
),
669 'max_downloads': opts
.max_downloads
,
670 'prefer_free_formats': opts
.prefer_free_formats
,
671 'verbose': opts
.verbose
,
672 'dump_intermediate_pages': opts
.dump_intermediate_pages
,
673 'write_pages': opts
.write_pages
,
675 'keepvideo': opts
.keepvideo
,
676 'min_filesize': opts
.min_filesize
,
677 'max_filesize': opts
.max_filesize
,
679 'cachedir': opts
.cachedir
,
680 'youtube_print_sig_code': opts
.youtube_print_sig_code
,
681 'age_limit': opts
.age_limit
,
682 'download_archive': opts
.download_archive
,
683 'cookiefile': opts
.cookiefile
,
684 'nocheckcertificate': opts
.no_check_certificate
,
686 'socket_timeout': opts
.socket_timeout
,
689 with YoutubeDL(ydl_opts
) as ydl
:
690 ydl
.print_debug_header()
691 ydl
.add_default_info_extractors()
694 # Add the metadata pp first, the other pps will copy it
696 ydl
.add_post_processor(FFmpegMetadataPP())
697 if opts
.extractaudio
:
698 ydl
.add_post_processor(FFmpegExtractAudioPP(preferredcodec
=opts
.audioformat
, preferredquality
=opts
.audioquality
, nopostoverwrites
=opts
.nopostoverwrites
))
700 ydl
.add_post_processor(FFmpegVideoConvertor(preferedformat
=opts
.recodevideo
))
701 if opts
.embedsubtitles
:
702 ydl
.add_post_processor(FFmpegEmbedSubtitlePP(subtitlesformat
=opts
.subtitlesformat
))
706 update_self(ydl
.to_screen
, opts
.verbose
)
709 if len(all_urls
) < 1:
710 if not opts
.update_self
:
711 parser
.error(u
'you must provide at least one URL')
716 retcode
= ydl
.download(all_urls
)
717 except MaxDownloadsReached
:
718 ydl
.to_screen(u
'--max-download limit reached, aborting.')
727 except DownloadError
:
729 except SameFileError
:
730 sys
.exit(u
'ERROR: fixed output name but more than one file to download')
731 except KeyboardInterrupt:
732 sys
.exit(u
'\nERROR: Interrupted by user')