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