]> jfr.im git - yt-dlp.git/blame - youtube_dl/__init__.py
Disable way and tf1 tests, the whole videos are served sometimes, so the md5 sum...
[yt-dlp.git] / youtube_dl / __init__.py
CommitLineData
235b3ba4
PH
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
3906e6ce 4__authors__ = (
59ae15a5
PH
5 'Ricardo Garcia Gonzalez',
6 'Danny Colligan',
7 'Benjamin Johnson',
8 'Vasyl\' Vavrychuk',
9 'Witold Baryluk',
10 'Paweł Paprota',
11 'Gergely Imreh',
12 'Rogério Brito',
13 'Philipp Hagemeister',
14 'Sören Schulze',
15 'Kevin Ngo',
16 'Ori Avtalion',
17 'shizeeg',
18 'Filippo Valsorda',
19 'Christian Albrecht',
88f6c78b 20 'Dave Vasilevsky',
2069acc6 21 'Jaime Marquínez Ferrándiz',
fffec3b9 22 'Jeff Crouse',
6aabe820 23 'Osama Khalid',
e8600d69 24 'Michael Walter',
95464f14 25 'M. Yasoob Ullah Khalid',
0ae456f0 26 'Julien Fraichard',
be74864a 27 'Johny Mo Swag',
df725153 28 'Axel Noack',
ba7a1de0
PH
29 'Albert Kim',
30)
235b3ba4
PH
31
32__license__ = 'Public Domain'
235b3ba4 33
0d94f247 34import codecs
c9ed14e6 35import getpass
c9ed14e6 36import optparse
235b3ba4 37import os
0f818663 38import random
235b3ba4 39import re
c9ed14e6 40import shlex
235b3ba4 41import socket
235b3ba4
PH
42import subprocess
43import sys
235b3ba4 44import warnings
4e38899e 45import platform
235b3ba4 46
9e8056d5 47from .utils import *
d5ed35b6 48from .update import update_self
f427df17 49from .version import __version__
9e8056d5 50from .FileDownloader import *
0824c28c 51from .extractor import gen_extractors
8222d8de 52from .YoutubeDL import YoutubeDL
9e8056d5 53from .PostProcessor import *
235b3ba4 54
75b5c590 55def parseOpts(overrideArguments=None):
59ae15a5
PH
56 def _readOptions(filename_bytes):
57 try:
58 optionf = open(filename_bytes)
59 except IOError:
60 return [] # silently skip if file is not present
61 try:
62 res = []
63 for l in optionf:
64 res += shlex.split(l, comments=True)
65 finally:
66 optionf.close()
67 return res
68
69 def _format_option_string(option):
70 ''' ('-o', '--option') -> -o, --format METAVAR'''
71
72 opts = []
73
74 if option._short_opts:
75 opts.append(option._short_opts[0])
76 if option._long_opts:
77 opts.append(option._long_opts[0])
78 if len(opts) > 1:
79 opts.insert(1, ', ')
80
81 if option.takes_value(): opts.append(' %s' % option.metavar)
82
83 return "".join(opts)
84
85 def _find_term_columns():
86 columns = os.environ.get('COLUMNS', None)
87 if columns:
88 return int(columns)
89
90 try:
91 sp = subprocess.Popen(['stty', 'size'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
92 out,err = sp.communicate()
93 return int(out.split()[1])
94 except:
95 pass
96 return None
97
98 max_width = 80
99 max_help_position = 80
100
101 # No need to wrap help messages if we're on a wide console
102 columns = _find_term_columns()
103 if columns: max_width = columns
104
105 fmt = optparse.IndentedHelpFormatter(width=max_width, max_help_position=max_help_position)
106 fmt.format_option_strings = _format_option_string
107
108 kw = {
109 'version' : __version__,
110 'formatter' : fmt,
111 'usage' : '%prog [options] url [url...]',
112 'conflict_handler' : 'resolve',
113 }
114
115 parser = optparse.OptionParser(**kw)
116
117 # option groups
118 general = optparse.OptionGroup(parser, 'General Options')
119 selection = optparse.OptionGroup(parser, 'Video Selection')
120 authentication = optparse.OptionGroup(parser, 'Authentication Options')
121 video_format = optparse.OptionGroup(parser, 'Video Format Options')
0beb3add 122 downloader = optparse.OptionGroup(parser, 'Download Options')
59ae15a5
PH
123 postproc = optparse.OptionGroup(parser, 'Post-processing Options')
124 filesystem = optparse.OptionGroup(parser, 'Filesystem Options')
125 verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options')
126
127 general.add_option('-h', '--help',
128 action='help', help='print this help text and exit')
129 general.add_option('-v', '--version',
130 action='version', help='print program version and exit')
131 general.add_option('-U', '--update',
f631c331 132 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)')
59ae15a5
PH
133 general.add_option('-i', '--ignore-errors',
134 action='store_true', dest='ignoreerrors', help='continue on download errors', default=False)
59ae15a5
PH
135 general.add_option('--dump-user-agent',
136 action='store_true', dest='dump_user_agent',
137 help='display the current browser identification', default=False)
138 general.add_option('--user-agent',
139 dest='user_agent', help='specify a custom user agent', metavar='UA')
28535652 140 general.add_option('--referer',
3820df01
JMF
141 dest='referer', help='specify a custom referer, use if the video access is restricted to one domain',
142 metavar='REF', default=None)
59ae15a5
PH
143 general.add_option('--list-extractors',
144 action='store_true', dest='list_extractors',
145 help='List all supported extractors and the URLs they would handle', default=False)
62067cb9 146 general.add_option('--extractor-descriptions',
0f818663
PH
147 action='store_true', dest='list_extractor_descriptions',
148 help='Output descriptions of all supported extractors', default=False)
dbc50fdf 149 general.add_option('--proxy', dest='proxy', default=None, help='Use the specified HTTP/HTTPS proxy', metavar='URL')
ea6d901e 150 general.add_option('--no-check-certificate', action='store_true', dest='no_check_certificate', default=False, help='Suppress HTTPS certificate validation.')
0beb3add 151
59ae15a5
PH
152
153 selection.add_option('--playlist-start',
154 dest='playliststart', metavar='NUMBER', help='playlist video to start at (default is %default)', default=1)
155 selection.add_option('--playlist-end',
156 dest='playlistend', metavar='NUMBER', help='playlist video to end at (default is last)', default=-1)
157 selection.add_option('--match-title', dest='matchtitle', metavar='REGEX',help='download only matching titles (regex or caseless sub-string)')
158 selection.add_option('--reject-title', dest='rejecttitle', metavar='REGEX',help='skip download for matching titles (regex or caseless sub-string)')
159 selection.add_option('--max-downloads', metavar='NUMBER', dest='max_downloads', help='Abort after downloading NUMBER files', default=None)
dbf2ba3d
PH
160 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)
161 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)
bd558525
JMF
162 selection.add_option('--date', metavar='DATE', dest='date', help='download only videos uploaded in this date', default=None)
163 selection.add_option('--datebefore', metavar='DATE', dest='datebefore', help='download only videos uploaded before this date', default=None)
164 selection.add_option('--dateafter', metavar='DATE', dest='dateafter', help='download only videos uploaded after this date', default=None)
9e982f9e
JC
165
166
59ae15a5
PH
167 authentication.add_option('-u', '--username',
168 dest='username', metavar='USERNAME', help='account username')
169 authentication.add_option('-p', '--password',
170 dest='password', metavar='PASSWORD', help='account password')
171 authentication.add_option('-n', '--netrc',
172 action='store_true', dest='usenetrc', help='use .netrc authentication data', default=False)
c6c19746
JMF
173 authentication.add_option('--video-password',
174 dest='videopassword', metavar='PASSWORD', help='video password (vimeo only)')
59ae15a5
PH
175
176
177 video_format.add_option('-f', '--format',
f4b659f7
JMF
178 action='store', dest='format', metavar='FORMAT',
179 help='video format code, specifiy the order of preference using slashes: "-f 22/17/18"')
59ae15a5
PH
180 video_format.add_option('--all-formats',
181 action='store_const', dest='format', help='download all available video formats', const='all')
182 video_format.add_option('--prefer-free-formats',
183 action='store_true', dest='prefer_free_formats', default=False, help='prefer free video formats unless a specific one is requested')
184 video_format.add_option('--max-quality',
185 action='store', dest='format_limit', metavar='FORMAT', help='highest quality format to download')
186 video_format.add_option('-F', '--list-formats',
187 action='store_true', dest='listformats', help='list all available formats (currently youtube only)')
b9fc4284 188 video_format.add_option('--write-sub', '--write-srt',
59ae15a5 189 action='store_true', dest='writesubtitles',
553d0974 190 help='write subtitle file (currently youtube only)', default=False)
b004821f
JMF
191 video_format.add_option('--write-auto-sub', '--write-automatic-sub',
192 action='store_true', dest='writeautomaticsub',
193 help='write automatic subtitle file (currently youtube only)', default=False)
553d0974 194 video_format.add_option('--only-sub',
1bd96c3a
PH
195 action='store_true', dest='skip_download',
196 help='[deprecated] alias of --skip-download', default=False)
553d0974 197 video_format.add_option('--all-subs',
ae608b80
IM
198 action='store_true', dest='allsubtitles',
199 help='downloads all the available subtitles of the video (currently youtube only)', default=False)
2a4093ea
IM
200 video_format.add_option('--list-subs',
201 action='store_true', dest='listsubtitles',
202 help='lists all available subtitles for the video (currently youtube only)', default=False)
9e62bc44 203 video_format.add_option('--sub-format',
c3ab8f86 204 action='store', dest='subtitlesformat', metavar='FORMAT',
65cceef8 205 help='subtitle format [srt/sbv/vtt] (default=srt) (currently youtube only)', default='srt')
b9fc4284 206 video_format.add_option('--sub-lang', '--srt-lang',
59ae15a5 207 action='store', dest='subtitleslang', metavar='LANG',
553d0974 208 help='language of the subtitles to download (optional) use IETF language tags like \'en\'')
59ae15a5 209
0beb3add
PH
210 downloader.add_option('-r', '--rate-limit',
211 dest='ratelimit', metavar='LIMIT', help='maximum download rate (e.g. 50k or 44.6m)')
212 downloader.add_option('-R', '--retries',
213 dest='retries', metavar='RETRIES', help='number of retries (default is %default)', default=10)
214 downloader.add_option('--buffer-size',
215 dest='buffersize', metavar='SIZE', help='size of download buffer (e.g. 1024 or 16k) (default is %default)', default="1024")
216 downloader.add_option('--no-resize-buffer',
217 action='store_true', dest='noresizebuffer',
218 help='do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE.', default=False)
219 downloader.add_option('--test', action='store_true', dest='test', default=False, help=optparse.SUPPRESS_HELP)
220
59ae15a5
PH
221 verbosity.add_option('-q', '--quiet',
222 action='store_true', dest='quiet', help='activates quiet mode', default=False)
223 verbosity.add_option('-s', '--simulate',
224 action='store_true', dest='simulate', help='do not download the video and do not write anything to disk', default=False)
225 verbosity.add_option('--skip-download',
226 action='store_true', dest='skip_download', help='do not download the video', default=False)
227 verbosity.add_option('-g', '--get-url',
228 action='store_true', dest='geturl', help='simulate, quiet but print URL', default=False)
229 verbosity.add_option('-e', '--get-title',
230 action='store_true', dest='gettitle', help='simulate, quiet but print title', default=False)
1a2adf3f 231 verbosity.add_option('--get-id',
232 action='store_true', dest='getid', help='simulate, quiet but print id', default=False)
59ae15a5
PH
233 verbosity.add_option('--get-thumbnail',
234 action='store_true', dest='getthumbnail',
235 help='simulate, quiet but print thumbnail URL', default=False)
236 verbosity.add_option('--get-description',
237 action='store_true', dest='getdescription',
238 help='simulate, quiet but print video description', default=False)
239 verbosity.add_option('--get-filename',
240 action='store_true', dest='getfilename',
241 help='simulate, quiet but print output filename', default=False)
242 verbosity.add_option('--get-format',
243 action='store_true', dest='getformat',
244 help='simulate, quiet but print output format', default=False)
7311fef8 245 verbosity.add_option('--newline',
5717d91a 246 action='store_true', dest='progress_with_newline', help='output progress bar as new lines', default=False)
59ae15a5
PH
247 verbosity.add_option('--no-progress',
248 action='store_true', dest='noprogress', help='do not print progress bar', default=False)
249 verbosity.add_option('--console-title',
250 action='store_true', dest='consoletitle',
251 help='display progress in console titlebar', default=False)
252 verbosity.add_option('-v', '--verbose',
253 action='store_true', dest='verbose', help='print various debugging information', default=False)
855703e5
PH
254 verbosity.add_option('--dump-intermediate-pages',
255 action='store_true', dest='dump_intermediate_pages', default=False,
256 help='print downloaded pages to debug problems(very verbose)')
59ae15a5 257
59ae15a5 258 filesystem.add_option('-t', '--title',
08b2ac74 259 action='store_true', dest='usetitle', help='use title in file name (default)', default=False)
59ae15a5 260 filesystem.add_option('--id',
08b2ac74 261 action='store_true', dest='useid', help='use only video ID in file name', default=False)
59ae15a5
PH
262 filesystem.add_option('-l', '--literal',
263 action='store_true', dest='usetitle', help='[deprecated] alias of --title', default=False)
264 filesystem.add_option('-A', '--auto-number',
265 action='store_true', dest='autonumber',
266 help='number downloaded files starting from 00000', default=False)
267 filesystem.add_option('-o', '--output',
74e3452b
JMF
268 dest='outtmpl', metavar='TEMPLATE',
269 help=('output filename template. Use %(title)s to get the title, '
270 '%(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, '
271 '%(autonumber)s to get an automatically incremented number, '
272 '%(ext)s for the filename extension, %(upload_date)s for the upload date (YYYYMMDD), '
273 '%(extractor)s for the provider (youtube, metacafe, etc), '
274 '%(id)s for the video id , %(playlist)s for the playlist the video is in, '
275 '%(playlist_index)s for the position in the playlist and %% for a literal percent. '
276 'Use - to output to stdout. Can also be used to download to a different directory, '
277 'for example with -o \'/my/downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s\' .'))
213c31ae
SK
278 filesystem.add_option('--autonumber-size',
279 dest='autonumber_size', metavar='NUMBER',
280 help='Specifies the number of digits in %(autonumber)s when it is present in output filename template or --autonumber option is given')
59ae15a5
PH
281 filesystem.add_option('--restrict-filenames',
282 action='store_true', dest='restrictfilenames',
283 help='Restrict filenames to only ASCII characters, and avoid "&" and spaces in filenames', default=False)
284 filesystem.add_option('-a', '--batch-file',
285 dest='batchfile', metavar='FILE', help='file containing URLs to download (\'-\' for stdin)')
286 filesystem.add_option('-w', '--no-overwrites',
287 action='store_true', dest='nooverwrites', help='do not overwrite files', default=False)
288 filesystem.add_option('-c', '--continue',
289 action='store_true', dest='continue_dl', help='resume partially downloaded files', default=True)
290 filesystem.add_option('--no-continue',
291 action='store_false', dest='continue_dl',
292 help='do not resume partially downloaded files (restart from beginning)')
293 filesystem.add_option('--cookies',
294 dest='cookiefile', metavar='FILE', help='file to read cookies from and dump cookie jar in')
295 filesystem.add_option('--no-part',
296 action='store_true', dest='nopart', help='do not use .part files', default=False)
297 filesystem.add_option('--no-mtime',
298 action='store_false', dest='updatetime',
299 help='do not use the Last-modified header to set the file modification time', default=True)
300 filesystem.add_option('--write-description',
301 action='store_true', dest='writedescription',
302 help='write video description to a .description file', default=False)
303 filesystem.add_option('--write-info-json',
304 action='store_true', dest='writeinfojson',
305 help='write video metadata to a .info.json file', default=False)
11d9224e
PH
306 filesystem.add_option('--write-thumbnail',
307 action='store_true', dest='writethumbnail',
308 help='write thumbnail image to disk', default=False)
59ae15a5
PH
309
310
311 postproc.add_option('-x', '--extract-audio', action='store_true', dest='extractaudio', default=False,
312 help='convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe)')
313 postproc.add_option('--audio-format', metavar='FORMAT', dest='audioformat', default='best',
510e6f6d 314 help='"best", "aac", "vorbis", "mp3", "m4a", "opus", or "wav"; best by default')
59ae15a5
PH
315 postproc.add_option('--audio-quality', metavar='QUALITY', dest='audioquality', default='5',
316 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)')
7851b379
PH
317 postproc.add_option('--recode-video', metavar='FORMAT', dest='recodevideo', default=None,
318 help='Encode the video to another format if necessary (currently supported: mp4|flv|ogg|webm)')
59ae15a5
PH
319 postproc.add_option('-k', '--keep-video', action='store_true', dest='keepvideo', default=False,
320 help='keeps the video file on disk after the post-processing; the video is erased by default')
f0648fc1
BPG
321 postproc.add_option('--no-post-overwrites', action='store_true', dest='nopostoverwrites', default=False,
322 help='do not overwrite post-processed files; the post-processed files are overwritten by default')
59ae15a5
PH
323
324
325 parser.add_option_group(general)
326 parser.add_option_group(selection)
0beb3add 327 parser.add_option_group(downloader)
59ae15a5
PH
328 parser.add_option_group(filesystem)
329 parser.add_option_group(verbosity)
330 parser.add_option_group(video_format)
331 parser.add_option_group(authentication)
332 parser.add_option_group(postproc)
333
75b5c590
PH
334 if overrideArguments is not None:
335 opts, args = parser.parse_args(overrideArguments)
336 if opts.verbose:
93eb15c5 337 sys.stderr.write(u'[debug] Override config: ' + repr(overrideArguments) + '\n')
59ae15a5 338 else:
75b5c590
PH
339 xdg_config_home = os.environ.get('XDG_CONFIG_HOME')
340 if xdg_config_home:
341 userConfFile = os.path.join(xdg_config_home, 'youtube-dl.conf')
342 else:
343 userConfFile = os.path.join(os.path.expanduser('~'), '.config', 'youtube-dl.conf')
344 systemConf = _readOptions('/etc/youtube-dl.conf')
345 userConf = _readOptions(userConfFile)
346 commandLineConf = sys.argv[1:]
347 argv = systemConf + userConf + commandLineConf
348 opts, args = parser.parse_args(argv)
c76cb6d5 349 if opts.verbose:
93eb15c5
FV
350 sys.stderr.write(u'[debug] System config: ' + repr(systemConf) + '\n')
351 sys.stderr.write(u'[debug] User config: ' + repr(userConf) + '\n')
352 sys.stderr.write(u'[debug] Command-line args: ' + repr(commandLineConf) + '\n')
8c42c506 353
59ae15a5 354 return parser, opts, args
235b3ba4 355
b8ad4f02 356def _real_main(argv=None):
0d94f247
PH
357 # Compatibility fixes for Windows
358 if sys.platform == 'win32':
359 # https://github.com/rg3/youtube-dl/issues/820
360 codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
361
b8ad4f02 362 parser, opts, args = parseOpts(argv)
59ae15a5
PH
363
364 # Open appropriate CookieJar
365 if opts.cookiefile is None:
366 jar = compat_cookiejar.CookieJar()
367 else:
368 try:
369 jar = compat_cookiejar.MozillaCookieJar(opts.cookiefile)
229cac75 370 if os.access(opts.cookiefile, os.R_OK):
59ae15a5
PH
371 jar.load()
372 except (IOError, OSError) as err:
229cac75
PH
373 if opts.verbose:
374 traceback.print_exc()
375 sys.stderr.write(u'ERROR: unable to open cookie file\n')
376 sys.exit(101)
59ae15a5
PH
377 # Set user agent
378 if opts.user_agent is not None:
379 std_headers['User-Agent'] = opts.user_agent
28535652
BH
380
381 # Set referer
382 if opts.referer is not None:
383 std_headers['Referer'] = opts.referer
59ae15a5
PH
384
385 # Dump user agent
386 if opts.dump_user_agent:
93eb15c5 387 compat_print(std_headers['User-Agent'])
59ae15a5
PH
388 sys.exit(0)
389
390 # Batch file verification
391 batchurls = []
392 if opts.batchfile is not None:
393 try:
394 if opts.batchfile == '-':
395 batchfd = sys.stdin
396 else:
397 batchfd = open(opts.batchfile, 'r')
398 batchurls = batchfd.readlines()
399 batchurls = [x.strip() for x in batchurls]
400 batchurls = [x for x in batchurls if len(x) > 0 and not re.search(r'^[#/;]', x)]
401 except IOError:
402 sys.exit(u'ERROR: batch file could not be read')
403 all_urls = batchurls + args
404 all_urls = [url.strip() for url in all_urls]
405
406 # General configuration
407 cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
53f72b11
PH
408 if opts.proxy is not None:
409 if opts.proxy == '':
410 proxies = {}
411 else:
412 proxies = {'http': opts.proxy, 'https': opts.proxy}
5fb16555
PH
413 else:
414 proxies = compat_urllib_request.getproxies()
415 # Set HTTPS proxy to HTTP one if given (https://github.com/rg3/youtube-dl/issues/805)
416 if 'http' in proxies and 'https' not in proxies:
417 proxies['https'] = proxies['http']
434aca5b 418 proxy_handler = compat_urllib_request.ProxyHandler(proxies)
ea6d901e 419 https_handler = make_HTTPS_handler(opts)
c34407d1 420 opener = compat_urllib_request.build_opener(https_handler, proxy_handler, cookie_processor, YoutubeDLHandler())
59ae15a5
PH
421 compat_urllib_request.install_opener(opener)
422 socket.setdefaulttimeout(300) # 5 minutes should be enough (famous last words)
423
424 extractors = gen_extractors()
425
426 if opts.list_extractors:
7dba9cd0 427 for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()):
93eb15c5 428 compat_print(ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie._WORKING else ''))
1a2c3c0f
FV
429 matchedUrls = [url for url in all_urls if ie.suitable(url)]
430 all_urls = [url for url in all_urls if url not in matchedUrls]
59ae15a5 431 for mu in matchedUrls:
93eb15c5 432 compat_print(u' ' + mu)
59ae15a5 433 sys.exit(0)
0f818663
PH
434 if opts.list_extractor_descriptions:
435 for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()):
436 if not ie._WORKING:
437 continue
438 desc = getattr(ie, 'IE_DESC', ie.IE_NAME)
439 if hasattr(ie, 'SEARCH_KEY'):
440 _SEARCHES = (u'cute kittens', u'slithering pythons', u'falling cat', u'angry poodle', u'purple fish', u'running tortoise')
441 _COUNTS = (u'', u'5', u'10', u'all')
442 desc += u' (Example: "%s%s:%s" )' % (ie.SEARCH_KEY, random.choice(_COUNTS), random.choice(_SEARCHES))
443 compat_print(desc)
444 sys.exit(0)
445
59ae15a5
PH
446
447 # Conflicting, missing and erroneous options
448 if opts.usenetrc and (opts.username is not None or opts.password is not None):
449 parser.error(u'using .netrc conflicts with giving username/password')
450 if opts.password is not None and opts.username is None:
c6c19746 451 parser.error(u' account username missing\n')
59ae15a5
PH
452 if opts.outtmpl is not None and (opts.usetitle or opts.autonumber or opts.useid):
453 parser.error(u'using output template conflicts with using title, video ID or auto number')
454 if opts.usetitle and opts.useid:
455 parser.error(u'using title conflicts with using video ID')
456 if opts.username is not None and opts.password is None:
457 opts.password = getpass.getpass(u'Type account password and press return:')
458 if opts.ratelimit is not None:
459 numeric_limit = FileDownloader.parse_bytes(opts.ratelimit)
460 if numeric_limit is None:
461 parser.error(u'invalid rate limit specified')
462 opts.ratelimit = numeric_limit
9e982f9e
JC
463 if opts.min_filesize is not None:
464 numeric_limit = FileDownloader.parse_bytes(opts.min_filesize)
465 if numeric_limit is None:
466 parser.error(u'invalid min_filesize specified')
467 opts.min_filesize = numeric_limit
468 if opts.max_filesize is not None:
469 numeric_limit = FileDownloader.parse_bytes(opts.max_filesize)
470 if numeric_limit is None:
471 parser.error(u'invalid max_filesize specified')
472 opts.max_filesize = numeric_limit
59ae15a5
PH
473 if opts.retries is not None:
474 try:
475 opts.retries = int(opts.retries)
476 except (TypeError, ValueError) as err:
477 parser.error(u'invalid retry count specified')
478 if opts.buffersize is not None:
479 numeric_buffersize = FileDownloader.parse_bytes(opts.buffersize)
480 if numeric_buffersize is None:
481 parser.error(u'invalid buffer size specified')
482 opts.buffersize = numeric_buffersize
483 try:
484 opts.playliststart = int(opts.playliststart)
485 if opts.playliststart <= 0:
486 raise ValueError(u'Playlist start must be positive')
487 except (TypeError, ValueError) as err:
488 parser.error(u'invalid playlist start number specified')
489 try:
490 opts.playlistend = int(opts.playlistend)
491 if opts.playlistend != -1 and (opts.playlistend <= 0 or opts.playlistend < opts.playliststart):
492 raise ValueError(u'Playlist end must be greater than playlist start')
493 except (TypeError, ValueError) as err:
494 parser.error(u'invalid playlist end number specified')
495 if opts.extractaudio:
510e6f6d 496 if opts.audioformat not in ['best', 'aac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav']:
59ae15a5
PH
497 parser.error(u'invalid audio format specified')
498 if opts.audioquality:
499 opts.audioquality = opts.audioquality.strip('k').strip('K')
500 if not opts.audioquality.isdigit():
501 parser.error(u'invalid audio quality specified')
7851b379
PH
502 if opts.recodevideo is not None:
503 if opts.recodevideo not in ['mp4', 'flv', 'webm', 'ogg']:
504 parser.error(u'invalid video recode format specified')
bd558525
JMF
505 if opts.date is not None:
506 date = DateRange.day(opts.date)
507 else:
508 date = DateRange(opts.dateafter, opts.datebefore)
59ae15a5 509
5cb9c312
PH
510 if sys.version_info < (3,):
511 # In Python 2, sys.argv is a bytestring (also note http://bugs.python.org/issue2128 for Windows systems)
0be41ec2
PH
512 if opts.outtmpl is not None:
513 opts.outtmpl = opts.outtmpl.decode(preferredencoding())
5cb9c312
PH
514 outtmpl =((opts.outtmpl is not None and opts.outtmpl)
515 or (opts.format == '-1' and opts.usetitle and u'%(title)s-%(id)s-%(format)s.%(ext)s')
516 or (opts.format == '-1' and u'%(id)s-%(format)s.%(ext)s')
517 or (opts.usetitle and opts.autonumber and u'%(autonumber)s-%(title)s-%(id)s.%(ext)s')
518 or (opts.usetitle and u'%(title)s-%(id)s.%(ext)s')
519 or (opts.useid and u'%(id)s.%(ext)s')
520 or (opts.autonumber and u'%(autonumber)s-%(id)s.%(ext)s')
08b2ac74 521 or u'%(title)s-%(id)s.%(ext)s')
8271226a 522
8222d8de
JMF
523 # YoutubeDL
524 ydl = YoutubeDL({
59ae15a5
PH
525 'usenetrc': opts.usenetrc,
526 'username': opts.username,
527 'password': opts.password,
c6c19746 528 'videopassword': opts.videopassword,
1a2adf3f 529 'quiet': (opts.quiet or opts.geturl or opts.gettitle or opts.getid or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat),
59ae15a5
PH
530 'forceurl': opts.geturl,
531 'forcetitle': opts.gettitle,
1a2adf3f 532 'forceid': opts.getid,
59ae15a5
PH
533 'forcethumbnail': opts.getthumbnail,
534 'forcedescription': opts.getdescription,
535 'forcefilename': opts.getfilename,
536 'forceformat': opts.getformat,
537 'simulate': opts.simulate,
1a2adf3f 538 '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),
59ae15a5
PH
539 'format': opts.format,
540 'format_limit': opts.format_limit,
541 'listformats': opts.listformats,
5cb9c312 542 'outtmpl': outtmpl,
213c31ae 543 'autonumber_size': opts.autonumber_size,
59ae15a5
PH
544 'restrictfilenames': opts.restrictfilenames,
545 'ignoreerrors': opts.ignoreerrors,
546 'ratelimit': opts.ratelimit,
547 'nooverwrites': opts.nooverwrites,
548 'retries': opts.retries,
549 'buffersize': opts.buffersize,
550 'noresizebuffer': opts.noresizebuffer,
551 'continuedl': opts.continue_dl,
552 'noprogress': opts.noprogress,
5717d91a 553 'progress_with_newline': opts.progress_with_newline,
59ae15a5
PH
554 'playliststart': opts.playliststart,
555 'playlistend': opts.playlistend,
556 'logtostderr': opts.outtmpl == '-',
557 'consoletitle': opts.consoletitle,
558 'nopart': opts.nopart,
559 'updatetime': opts.updatetime,
560 'writedescription': opts.writedescription,
561 'writeinfojson': opts.writeinfojson,
11d9224e 562 'writethumbnail': opts.writethumbnail,
59ae15a5 563 'writesubtitles': opts.writesubtitles,
b004821f 564 'writeautomaticsub': opts.writeautomaticsub,
ae608b80 565 'allsubtitles': opts.allsubtitles,
2a4093ea 566 'listsubtitles': opts.listsubtitles,
9e62bc44 567 'subtitlesformat': opts.subtitlesformat,
59ae15a5 568 'subtitleslang': opts.subtitleslang,
8271226a
PH
569 'matchtitle': decodeOption(opts.matchtitle),
570 'rejecttitle': decodeOption(opts.rejecttitle),
59ae15a5
PH
571 'max_downloads': opts.max_downloads,
572 'prefer_free_formats': opts.prefer_free_formats,
573 'verbose': opts.verbose,
855703e5 574 'dump_intermediate_pages': opts.dump_intermediate_pages,
8d5d3a5d 575 'test': opts.test,
7851b379 576 'keepvideo': opts.keepvideo,
9e982f9e 577 'min_filesize': opts.min_filesize,
bd558525 578 'max_filesize': opts.max_filesize,
11d9224e 579 'daterange': date,
59ae15a5
PH
580 })
581
582 if opts.verbose:
f3bab004 583 sys.stderr.write(u'[debug] youtube-dl version ' + __version__ + u'\n')
4e38899e 584 try:
deacef65
PH
585 sp = subprocess.Popen(
586 ['git', 'rev-parse', '--short', 'HEAD'],
587 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
588 cwd=os.path.dirname(os.path.abspath(__file__)))
4e38899e
FV
589 out, err = sp.communicate()
590 out = out.decode().strip()
591 if re.match('[0-9a-f]+', out):
f3bab004 592 sys.stderr.write(u'[debug] Git HEAD: ' + out + u'\n')
4e38899e 593 except:
de29c414
PH
594 try:
595 sys.exc_clear()
596 except:
597 pass
f3bab004
PH
598 sys.stderr.write(u'[debug] Python version %s - %s' %(platform.python_version(), platform.platform()) + u'\n')
599 sys.stderr.write(u'[debug] Proxy map: ' + str(proxy_handler.proxies) + u'\n')
59ae15a5 600
023fa8c4 601 ydl.add_default_info_extractors()
59ae15a5
PH
602
603 # PostProcessors
604 if opts.extractaudio:
8222d8de 605 ydl.add_post_processor(FFmpegExtractAudioPP(preferredcodec=opts.audioformat, preferredquality=opts.audioquality, nopostoverwrites=opts.nopostoverwrites))
7851b379 606 if opts.recodevideo:
8222d8de 607 ydl.add_post_processor(FFmpegVideoConvertor(preferedformat=opts.recodevideo))
59ae15a5 608
67353612
PH
609 # Update version
610 if opts.update_self:
8222d8de 611 update_self(ydl.to_screen, opts.verbose, sys.argv[0])
67353612 612
59ae15a5
PH
613 # Maybe do nothing
614 if len(all_urls) < 1:
615 if not opts.update_self:
616 parser.error(u'you must provide at least one URL')
617 else:
618 sys.exit()
619
620 try:
8222d8de 621 retcode = ydl.download(all_urls)
59ae15a5 622 except MaxDownloadsReached:
8222d8de 623 ydl.to_screen(u'--max-download limit reached, aborting.')
59ae15a5
PH
624 retcode = 101
625
626 # Dump cookie jar if requested
627 if opts.cookiefile is not None:
628 try:
629 jar.save()
630 except (IOError, OSError) as err:
631 sys.exit(u'ERROR: unable to save cookie jar')
632
633 sys.exit(retcode)
235b3ba4 634
b8ad4f02 635def main(argv=None):
59ae15a5 636 try:
b8ad4f02 637 _real_main(argv)
59ae15a5
PH
638 except DownloadError:
639 sys.exit(1)
640 except SameFileError:
641 sys.exit(u'ERROR: fixed output name but more than one file to download')
642 except KeyboardInterrupt:
643 sys.exit(u'\nERROR: Interrupted by user')