| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | #!/usr/bin/env python | 
					
						
							|  |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | __license__ = 'Public Domain' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-04 07:09:50 +02:00
										 |  |  | import codecs | 
					
						
							| 
									
										
										
										
											2014-02-25 17:31:16 -05:00
										 |  |  | import io | 
					
						
							| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2013-07-01 18:52:19 +02:00
										 |  |  | import random | 
					
						
							| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-28 12:57:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-13 07:58:44 +02:00
										 |  |  | from .options import ( | 
					
						
							|  |  |  |     parseOpts, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2014-11-02 11:23:40 +01:00
										 |  |  | from .compat import ( | 
					
						
							| 
									
										
										
										
											2014-09-30 22:27:53 +07:00
										 |  |  |     compat_expanduser, | 
					
						
							| 
									
										
										
										
											2014-03-18 14:27:42 +01:00
										 |  |  |     compat_getpass, | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     compat_print, | 
					
						
							| 
									
										
										
										
											2014-11-19 18:21:58 +01:00
										 |  |  |     workaround_optparse_bug9161, | 
					
						
							| 
									
										
										
										
											2014-11-02 11:23:40 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | from .utils import ( | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     DateRange, | 
					
						
							| 
									
										
										
										
											2014-04-30 10:02:03 +02:00
										 |  |  |     DEFAULT_OUTTMPL, | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     decodeOption, | 
					
						
							|  |  |  |     DownloadError, | 
					
						
							|  |  |  |     MaxDownloadsReached, | 
					
						
							|  |  |  |     preferredencoding, | 
					
						
							| 
									
										
										
										
											2014-02-25 01:43:17 +01:00
										 |  |  |     read_batch_urls, | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     SameFileError, | 
					
						
							| 
									
										
										
										
											2013-12-16 05:04:12 +01:00
										 |  |  |     setproctitle, | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     std_headers, | 
					
						
							|  |  |  |     write_string, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2012-12-30 19:49:14 +01:00
										 |  |  | from .update import update_self | 
					
						
							| 
									
										
										
										
											2014-07-23 02:43:59 +02:00
										 |  |  | from .downloader import ( | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  |     FileDownloader, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-06-23 22:42:59 +02:00
										 |  |  | from .extractor import gen_extractors | 
					
						
							| 
									
										
										
										
											2013-06-18 22:14:21 +02:00
										 |  |  | from .YoutubeDL import YoutubeDL | 
					
						
							| 
									
										
										
										
											2013-10-15 02:07:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-16 19:26:48 +02:00
										 |  |  | def _real_main(argv=None): | 
					
						
							| 
									
										
										
										
											2013-05-04 07:09:50 +02:00
										 |  |  |     # Compatibility fixes for Windows | 
					
						
							|  |  |  |     if sys.platform == 'win32': | 
					
						
							|  |  |  |         # https://github.com/rg3/youtube-dl/issues/820 | 
					
						
							|  |  |  |         codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-19 18:21:58 +01:00
										 |  |  |     workaround_optparse_bug9161() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |     setproctitle('youtube-dl') | 
					
						
							| 
									
										
										
										
											2013-12-16 05:04:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-16 19:26:48 +02:00
										 |  |  |     parser, opts, args = parseOpts(argv) | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Set user agent | 
					
						
							|  |  |  |     if opts.user_agent is not None: | 
					
						
							|  |  |  |         std_headers['User-Agent'] = opts.user_agent | 
					
						
							| 
									
										
										
										
											2013-08-08 09:53:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-24 13:56:04 +02:00
										 |  |  |     # Set referer | 
					
						
							|  |  |  |     if opts.referer is not None: | 
					
						
							|  |  |  |         std_headers['Referer'] = opts.referer | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 16:34:05 +01:00
										 |  |  |     # Custom HTTP headers | 
					
						
							|  |  |  |     if opts.headers is not None: | 
					
						
							|  |  |  |         for h in opts.headers: | 
					
						
							|  |  |  |             if h.find(':', 1) < 0: | 
					
						
							| 
									
										
										
										
											2014-11-23 21:20:46 +01:00
										 |  |  |                 parser.error('wrong header formatting, it should be key:value, not "%s"' % h) | 
					
						
							| 
									
										
										
										
											2014-03-11 16:34:05 +01:00
										 |  |  |             key, value = h.split(':', 2) | 
					
						
							|  |  |  |             if opts.verbose: | 
					
						
							| 
									
										
										
										
											2014-11-23 21:20:46 +01:00
										 |  |  |                 write_string('[debug] Adding header from command line option %s:%s\n' % (key, value)) | 
					
						
							| 
									
										
										
										
											2014-03-11 16:34:05 +01:00
										 |  |  |             std_headers[key] = value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     # Dump user agent | 
					
						
							|  |  |  |     if opts.dump_user_agent: | 
					
						
							| 
									
										
										
										
											2013-06-24 15:57:53 +02:00
										 |  |  |         compat_print(std_headers['User-Agent']) | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         sys.exit(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Batch file verification | 
					
						
							| 
									
										
										
										
											2014-02-25 01:43:17 +01:00
										 |  |  |     batch_urls = [] | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.batchfile is not None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             if opts.batchfile == '-': | 
					
						
							|  |  |  |                 batchfd = sys.stdin | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2014-02-25 01:43:17 +01:00
										 |  |  |                 batchfd = io.open(opts.batchfile, 'r', encoding='utf-8', errors='ignore') | 
					
						
							|  |  |  |             batch_urls = read_batch_urls(batchfd) | 
					
						
							| 
									
										
										
										
											2013-07-30 23:11:44 +02:00
										 |  |  |             if opts.verbose: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |                 write_string('[debug] Batch file urls: ' + repr(batch_urls) + '\n') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         except IOError: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             sys.exit('ERROR: batch file could not be read') | 
					
						
							| 
									
										
										
										
											2014-02-25 01:43:17 +01:00
										 |  |  |     all_urls = batch_urls + args | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     all_urls = [url.strip() for url in all_urls] | 
					
						
							| 
									
										
										
										
											2014-01-05 05:24:50 +01:00
										 |  |  |     _enc = preferredencoding() | 
					
						
							| 
									
										
										
										
											2014-01-05 10:58:36 +01:00
										 |  |  |     all_urls = [url.decode(_enc, 'ignore') if isinstance(url, bytes) else url for url in all_urls] | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     extractors = gen_extractors() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if opts.list_extractors: | 
					
						
							| 
									
										
										
										
											2013-07-01 18:21:29 +02:00
										 |  |  |         for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()): | 
					
						
							| 
									
										
										
										
											2013-06-24 15:57:53 +02:00
										 |  |  |             compat_print(ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie._WORKING else '')) | 
					
						
							| 
									
										
										
										
											2012-12-20 14:18:23 +01:00
										 |  |  |             matchedUrls = [url for url in all_urls if ie.suitable(url)] | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |             for mu in matchedUrls: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |                 compat_print('  ' + mu) | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         sys.exit(0) | 
					
						
							| 
									
										
										
										
											2013-07-01 18:52:19 +02:00
										 |  |  |     if opts.list_extractor_descriptions: | 
					
						
							|  |  |  |         for ie in sorted(extractors, key=lambda ie: ie.IE_NAME.lower()): | 
					
						
							|  |  |  |             if not ie._WORKING: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             desc = getattr(ie, 'IE_DESC', ie.IE_NAME) | 
					
						
							| 
									
										
										
										
											2013-10-07 12:21:24 +02:00
										 |  |  |             if desc is False: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2013-07-01 18:52:19 +02:00
										 |  |  |             if hasattr(ie, 'SEARCH_KEY'): | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |                 _SEARCHES = ('cute kittens', 'slithering pythons', 'falling cat', 'angry poodle', 'purple fish', 'running tortoise', 'sleeping bunny') | 
					
						
							|  |  |  |                 _COUNTS = ('', '5', '10', 'all') | 
					
						
							|  |  |  |                 desc += ' (Example: "%s%s:%s" )' % (ie.SEARCH_KEY, random.choice(_COUNTS), random.choice(_SEARCHES)) | 
					
						
							| 
									
										
										
										
											2013-07-01 18:52:19 +02:00
										 |  |  |             compat_print(desc) | 
					
						
							|  |  |  |         sys.exit(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     # Conflicting, missing and erroneous options | 
					
						
							|  |  |  |     if opts.usenetrc and (opts.username is not None or opts.password is not None): | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         parser.error('using .netrc conflicts with giving username/password') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.password is not None and opts.username is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         parser.error('account username missing\n') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.outtmpl is not None and (opts.usetitle or opts.autonumber or opts.useid): | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         parser.error('using output template conflicts with using title, video ID or auto number') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.usetitle and opts.useid: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         parser.error('using title conflicts with using video ID') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.username is not None and opts.password is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         opts.password = compat_getpass('Type account password and press [Return]: ') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.ratelimit is not None: | 
					
						
							|  |  |  |         numeric_limit = FileDownloader.parse_bytes(opts.ratelimit) | 
					
						
							|  |  |  |         if numeric_limit is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid rate limit specified') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         opts.ratelimit = numeric_limit | 
					
						
							| 
									
										
										
										
											2013-01-22 00:50:42 -05:00
										 |  |  |     if opts.min_filesize is not None: | 
					
						
							|  |  |  |         numeric_limit = FileDownloader.parse_bytes(opts.min_filesize) | 
					
						
							|  |  |  |         if numeric_limit is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid min_filesize specified') | 
					
						
							| 
									
										
										
										
											2013-01-22 00:50:42 -05:00
										 |  |  |         opts.min_filesize = numeric_limit | 
					
						
							|  |  |  |     if opts.max_filesize is not None: | 
					
						
							|  |  |  |         numeric_limit = FileDownloader.parse_bytes(opts.max_filesize) | 
					
						
							|  |  |  |         if numeric_limit is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid max_filesize specified') | 
					
						
							| 
									
										
										
										
											2013-01-22 00:50:42 -05:00
										 |  |  |         opts.max_filesize = numeric_limit | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.retries is not None: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             opts.retries = int(opts.retries) | 
					
						
							| 
									
										
										
										
											2013-11-22 19:57:52 +01:00
										 |  |  |         except (TypeError, ValueError): | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid retry count specified') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.buffersize is not None: | 
					
						
							|  |  |  |         numeric_buffersize = FileDownloader.parse_bytes(opts.buffersize) | 
					
						
							|  |  |  |         if numeric_buffersize is None: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid buffer size specified') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         opts.buffersize = numeric_buffersize | 
					
						
							| 
									
										
										
										
											2013-12-16 13:16:20 +01:00
										 |  |  |     if opts.playliststart <= 0: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         raise ValueError('Playlist start must be positive') | 
					
						
							| 
									
										
										
										
											2013-12-16 13:16:20 +01:00
										 |  |  |     if opts.playlistend not in (-1, None) and opts.playlistend < opts.playliststart: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         raise ValueError('Playlist end must be greater than playlist start') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.extractaudio: | 
					
						
							| 
									
										
										
										
											2013-01-10 19:15:04 +01:00
										 |  |  |         if opts.audioformat not in ['best', 'aac', 'mp3', 'm4a', 'opus', 'vorbis', 'wav']: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid audio format specified') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     if opts.audioquality: | 
					
						
							|  |  |  |         opts.audioquality = opts.audioquality.strip('k').strip('K') | 
					
						
							|  |  |  |         if not opts.audioquality.isdigit(): | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid audio quality specified') | 
					
						
							| 
									
										
										
										
											2013-01-12 15:07:59 +01:00
										 |  |  |     if opts.recodevideo is not None: | 
					
						
							| 
									
										
										
										
											2014-05-10 15:09:56 +02:00
										 |  |  |         if opts.recodevideo not in ['mp4', 'flv', 'webm', 'ogg', 'mkv']: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             parser.error('invalid video recode format specified') | 
					
						
							| 
									
										
										
										
											2013-04-27 14:01:55 +02:00
										 |  |  |     if opts.date is not None: | 
					
						
							|  |  |  |         date = DateRange.day(opts.date) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         date = DateRange(opts.dateafter, opts.datebefore) | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-22 14:53:23 +01:00
										 |  |  |     # Do not download videos when there are audio-only formats | 
					
						
							|  |  |  |     if opts.extractaudio and not opts.keepvideo and opts.format is None: | 
					
						
							|  |  |  |         opts.format = 'bestaudio/best' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-14 11:14:40 +02:00
										 |  |  |     # --all-sub automatically sets --write-sub if --write-auto-sub is not given | 
					
						
							|  |  |  |     # this was the old behaviour if only --all-sub was given. | 
					
						
							| 
									
										
										
										
											2014-11-23 22:21:46 +01:00
										 |  |  |     if opts.allsubtitles and not opts.writeautomaticsub: | 
					
						
							| 
									
										
										
										
											2013-09-14 11:14:40 +02:00
										 |  |  |         opts.writesubtitles = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-15 17:44:48 +01:00
										 |  |  |     if sys.version_info < (3,): | 
					
						
							|  |  |  |         # In Python 2, sys.argv is a bytestring (also note http://bugs.python.org/issue2128 for Windows systems) | 
					
						
							| 
									
										
										
										
											2012-12-15 23:54:44 +01:00
										 |  |  |         if opts.outtmpl is not None: | 
					
						
							|  |  |  |             opts.outtmpl = opts.outtmpl.decode(preferredencoding()) | 
					
						
							| 
									
										
										
										
											2014-11-23 20:41:03 +01:00
										 |  |  |     outtmpl = ((opts.outtmpl is not None and opts.outtmpl) | 
					
						
							| 
									
										
										
										
											2014-11-23 21:20:46 +01:00
										 |  |  |                or (opts.format == '-1' and opts.usetitle and '%(title)s-%(id)s-%(format)s.%(ext)s') | 
					
						
							|  |  |  |                or (opts.format == '-1' and '%(id)s-%(format)s.%(ext)s') | 
					
						
							|  |  |  |                or (opts.usetitle and opts.autonumber and '%(autonumber)s-%(title)s-%(id)s.%(ext)s') | 
					
						
							|  |  |  |                or (opts.usetitle and '%(title)s-%(id)s.%(ext)s') | 
					
						
							|  |  |  |                or (opts.useid and '%(id)s.%(ext)s') | 
					
						
							|  |  |  |                or (opts.autonumber and '%(autonumber)s-%(id)s.%(ext)s') | 
					
						
							|  |  |  |                or DEFAULT_OUTTMPL) | 
					
						
							| 
									
										
										
										
											2013-12-15 11:42:38 +01:00
										 |  |  |     if not os.path.splitext(outtmpl)[1] and opts.extractaudio: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         parser.error('Cannot download a video and extract audio into the same' | 
					
						
							|  |  |  |                      ' file! Use "{0}.%(ext)s" instead of "{0}" as the output' | 
					
						
							|  |  |  |                      ' template'.format(outtmpl)) | 
					
						
							| 
									
										
										
										
											2013-09-24 21:55:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-25 00:30:57 +02:00
										 |  |  |     any_printing = opts.geturl or opts.gettitle or opts.getid or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat or opts.getduration or opts.dumpjson or opts.dump_single_json | 
					
						
							| 
									
										
										
										
											2014-09-30 22:27:53 +07:00
										 |  |  |     download_archive_fn = compat_expanduser(opts.download_archive) if opts.download_archive is not None else opts.download_archive | 
					
						
							| 
									
										
										
										
											2013-12-16 04:15:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-15 01:06:25 +01:00
										 |  |  |     # PostProcessors | 
					
						
							|  |  |  |     postprocessors = [] | 
					
						
							|  |  |  |     # Add the metadata pp first, the other pps will copy it | 
					
						
							|  |  |  |     if opts.addmetadata: | 
					
						
							|  |  |  |         postprocessors.append({'key': 'FFmpegMetadata'}) | 
					
						
							|  |  |  |     if opts.extractaudio: | 
					
						
							|  |  |  |         postprocessors.append({ | 
					
						
							|  |  |  |             'key': 'FFmpegExtractAudio', | 
					
						
							|  |  |  |             'preferredcodec': opts.audioformat, | 
					
						
							|  |  |  |             'preferredquality': opts.audioquality, | 
					
						
							|  |  |  |             'nopostoverwrites': opts.nopostoverwrites, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     if opts.recodevideo: | 
					
						
							|  |  |  |         postprocessors.append({ | 
					
						
							|  |  |  |             'key': 'FFmpegVideoConvertor', | 
					
						
							|  |  |  |             'preferedformat': opts.recodevideo, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     if opts.embedsubtitles: | 
					
						
							|  |  |  |         postprocessors.append({ | 
					
						
							|  |  |  |             'key': 'FFmpegEmbedSubtitle', | 
					
						
							|  |  |  |             'subtitlesformat': opts.subtitlesformat, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     if opts.xattrs: | 
					
						
							|  |  |  |         postprocessors.append({'key': 'XAttrMetadata'}) | 
					
						
							|  |  |  |     if opts.embedthumbnail: | 
					
						
							|  |  |  |         if not opts.addmetadata: | 
					
						
							|  |  |  |             postprocessors.append({'key': 'FFmpegAudioFix'}) | 
					
						
							|  |  |  |         postprocessors.append({'key': 'AtomicParsley'}) | 
					
						
							|  |  |  |     # Please keep ExecAfterDownload towards the bottom as it allows the user to modify the final file in any way. | 
					
						
							|  |  |  |     # So if the user is able to remove the file before your postprocessor runs it might cause a few problems. | 
					
						
							|  |  |  |     if opts.exec_cmd: | 
					
						
							|  |  |  |         postprocessors.append({ | 
					
						
							|  |  |  |             'key': 'ExecAfterDownload', | 
					
						
							|  |  |  |             'verboseOutput': opts.verbose, | 
					
						
							|  |  |  |             'exec_cmd': opts.exec_cmd, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |     ydl_opts = { | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'usenetrc': opts.usenetrc, | 
					
						
							|  |  |  |         'username': opts.username, | 
					
						
							|  |  |  |         'password': opts.password, | 
					
						
							| 
									
										
										
										
											2014-08-16 14:28:41 -07:00
										 |  |  |         'twofactor': opts.twofactor, | 
					
						
							| 
									
										
										
										
											2013-06-25 22:22:32 +02:00
										 |  |  |         'videopassword': opts.videopassword, | 
					
						
							| 
									
										
										
										
											2013-12-16 04:15:10 +01:00
										 |  |  |         'quiet': (opts.quiet or any_printing), | 
					
						
							| 
									
										
										
										
											2014-03-26 00:43:46 +01:00
										 |  |  |         'no_warnings': opts.no_warnings, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'forceurl': opts.geturl, | 
					
						
							|  |  |  |         'forcetitle': opts.gettitle, | 
					
						
							| 
									
										
										
										
											2013-05-05 22:30:07 -07:00
										 |  |  |         'forceid': opts.getid, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'forcethumbnail': opts.getthumbnail, | 
					
						
							|  |  |  |         'forcedescription': opts.getdescription, | 
					
						
							| 
									
										
										
										
											2013-12-16 04:15:10 +01:00
										 |  |  |         'forceduration': opts.getduration, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'forcefilename': opts.getfilename, | 
					
						
							|  |  |  |         'forceformat': opts.getformat, | 
					
						
							| 
									
										
										
										
											2013-11-19 18:59:22 +05:00
										 |  |  |         'forcejson': opts.dumpjson, | 
					
						
							| 
									
										
										
										
											2014-10-25 00:30:57 +02:00
										 |  |  |         'dump_single_json': opts.dump_single_json, | 
					
						
							| 
									
										
										
										
											2014-10-26 13:01:57 +01:00
										 |  |  |         'simulate': opts.simulate or any_printing, | 
					
						
							|  |  |  |         'skip_download': opts.skip_download, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'format': opts.format, | 
					
						
							|  |  |  |         'format_limit': opts.format_limit, | 
					
						
							|  |  |  |         'listformats': opts.listformats, | 
					
						
							| 
									
										
										
										
											2012-12-15 17:44:48 +01:00
										 |  |  |         'outtmpl': outtmpl, | 
					
						
							| 
									
										
										
										
											2013-04-02 11:40:07 +07:00
										 |  |  |         'autonumber_size': opts.autonumber_size, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'restrictfilenames': opts.restrictfilenames, | 
					
						
							|  |  |  |         'ignoreerrors': opts.ignoreerrors, | 
					
						
							|  |  |  |         'ratelimit': opts.ratelimit, | 
					
						
							|  |  |  |         'nooverwrites': opts.nooverwrites, | 
					
						
							|  |  |  |         'retries': opts.retries, | 
					
						
							|  |  |  |         'buffersize': opts.buffersize, | 
					
						
							|  |  |  |         'noresizebuffer': opts.noresizebuffer, | 
					
						
							|  |  |  |         'continuedl': opts.continue_dl, | 
					
						
							|  |  |  |         'noprogress': opts.noprogress, | 
					
						
							| 
									
										
										
										
											2013-02-18 18:52:06 +01:00
										 |  |  |         'progress_with_newline': opts.progress_with_newline, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'playliststart': opts.playliststart, | 
					
						
							|  |  |  |         'playlistend': opts.playlistend, | 
					
						
							| 
									
										
										
										
											2014-07-10 20:11:11 -07:00
										 |  |  |         'playlistreverse': opts.playlist_reverse, | 
					
						
							| 
									
										
										
										
											2013-09-30 16:26:25 -04:00
										 |  |  |         'noplaylist': opts.noplaylist, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'logtostderr': opts.outtmpl == '-', | 
					
						
							|  |  |  |         'consoletitle': opts.consoletitle, | 
					
						
							|  |  |  |         'nopart': opts.nopart, | 
					
						
							|  |  |  |         'updatetime': opts.updatetime, | 
					
						
							|  |  |  |         'writedescription': opts.writedescription, | 
					
						
							| 
									
										
										
										
											2013-10-14 16:18:58 +11:00
										 |  |  |         'writeannotations': opts.writeannotations, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'writeinfojson': opts.writeinfojson, | 
					
						
							| 
									
										
										
										
											2013-05-01 14:04:33 +02:00
										 |  |  |         'writethumbnail': opts.writethumbnail, | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'writesubtitles': opts.writesubtitles, | 
					
						
							| 
									
										
										
										
											2013-06-25 23:45:16 +02:00
										 |  |  |         'writeautomaticsub': opts.writeautomaticsub, | 
					
						
							| 
									
										
										
										
											2013-02-22 02:52:55 +01:00
										 |  |  |         'allsubtitles': opts.allsubtitles, | 
					
						
							| 
									
										
										
										
											2013-02-22 04:50:05 +01:00
										 |  |  |         'listsubtitles': opts.listsubtitles, | 
					
						
							| 
									
										
										
										
											2013-02-22 03:53:54 +01:00
										 |  |  |         'subtitlesformat': opts.subtitlesformat, | 
					
						
							| 
									
										
										
										
											2013-09-06 16:26:22 +02:00
										 |  |  |         'subtitleslangs': opts.subtitleslangs, | 
					
						
							| 
									
										
										
										
											2013-02-21 17:09:39 +01:00
										 |  |  |         'matchtitle': decodeOption(opts.matchtitle), | 
					
						
							|  |  |  |         'rejecttitle': decodeOption(opts.rejecttitle), | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |         'max_downloads': opts.max_downloads, | 
					
						
							|  |  |  |         'prefer_free_formats': opts.prefer_free_formats, | 
					
						
							|  |  |  |         'verbose': opts.verbose, | 
					
						
							| 
									
										
										
										
											2013-04-11 18:31:35 +02:00
										 |  |  |         'dump_intermediate_pages': opts.dump_intermediate_pages, | 
					
						
							| 
									
										
										
										
											2013-10-28 10:44:02 +01:00
										 |  |  |         'write_pages': opts.write_pages, | 
					
						
							| 
									
										
										
										
											2012-12-11 09:57:40 +01:00
										 |  |  |         'test': opts.test, | 
					
						
							| 
									
										
										
										
											2013-01-12 15:07:59 +01:00
										 |  |  |         'keepvideo': opts.keepvideo, | 
					
						
							| 
									
										
										
										
											2013-01-22 00:50:42 -05:00
										 |  |  |         'min_filesize': opts.min_filesize, | 
					
						
							| 
									
										
										
										
											2013-04-27 14:01:55 +02:00
										 |  |  |         'max_filesize': opts.max_filesize, | 
					
						
							| 
									
										
										
										
											2013-12-16 03:09:49 +01:00
										 |  |  |         'min_views': opts.min_views, | 
					
						
							|  |  |  |         'max_views': opts.max_views, | 
					
						
							| 
									
										
										
										
											2013-05-01 14:04:33 +02:00
										 |  |  |         'daterange': date, | 
					
						
							| 
									
										
										
										
											2013-09-24 21:26:10 +02:00
										 |  |  |         'cachedir': opts.cachedir, | 
					
						
							| 
									
										
										
										
											2013-09-22 10:50:12 +02:00
										 |  |  |         'youtube_print_sig_code': opts.youtube_print_sig_code, | 
					
						
							| 
									
										
										
										
											2013-10-06 06:06:30 +02:00
										 |  |  |         'age_limit': opts.age_limit, | 
					
						
							| 
									
										
										
										
											2014-01-12 01:27:47 +01:00
										 |  |  |         'download_archive': download_archive_fn, | 
					
						
							| 
									
										
										
										
											2013-11-22 19:57:52 +01:00
										 |  |  |         'cookiefile': opts.cookiefile, | 
					
						
							|  |  |  |         'nocheckcertificate': opts.no_check_certificate, | 
					
						
							| 
									
										
										
										
											2014-03-21 00:33:53 +01:00
										 |  |  |         'prefer_insecure': opts.prefer_insecure, | 
					
						
							| 
									
										
										
										
											2013-11-26 08:03:11 +01:00
										 |  |  |         'proxy': opts.proxy, | 
					
						
							| 
									
										
										
										
											2013-12-02 13:37:05 +01:00
										 |  |  |         'socket_timeout': opts.socket_timeout, | 
					
						
							| 
									
										
										
										
											2013-12-09 04:08:51 +01:00
										 |  |  |         'bidi_workaround': opts.bidi_workaround, | 
					
						
							| 
									
										
										
										
											2013-12-29 15:28:32 +01:00
										 |  |  |         'debug_printtraffic': opts.debug_printtraffic, | 
					
						
							| 
									
										
										
										
											2014-01-08 17:53:34 +01:00
										 |  |  |         'prefer_ffmpeg': opts.prefer_ffmpeg, | 
					
						
							| 
									
										
										
										
											2014-01-21 02:09:49 +01:00
										 |  |  |         'include_ads': opts.include_ads, | 
					
						
							| 
									
										
										
										
											2014-01-22 14:16:43 +01:00
										 |  |  |         'default_search': opts.default_search, | 
					
						
							| 
									
										
										
										
											2014-01-22 21:56:37 +01:00
										 |  |  |         'youtube_include_dash_manifest': opts.youtube_include_dash_manifest, | 
					
						
							| 
									
										
										
										
											2014-03-30 06:02:41 +02:00
										 |  |  |         'encoding': opts.encoding, | 
					
						
							| 
									
										
										
										
											2014-08-25 10:18:01 +02:00
										 |  |  |         'exec_cmd': opts.exec_cmd, | 
					
						
							| 
									
										
										
										
											2014-10-24 14:48:12 +02:00
										 |  |  |         'extract_flat': opts.extract_flat, | 
					
						
							| 
									
										
										
										
											2014-12-15 01:06:25 +01:00
										 |  |  |         'postprocessors': postprocessors, | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |     with YoutubeDL(ydl_opts) as ydl: | 
					
						
							|  |  |  |         # Update version | 
					
						
							|  |  |  |         if opts.update_self: | 
					
						
							|  |  |  |             update_self(ydl.to_screen, opts.verbose) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-24 12:16:16 +02:00
										 |  |  |         # Remove cache dir | 
					
						
							|  |  |  |         if opts.rm_cachedir: | 
					
						
							| 
									
										
										
										
											2014-09-03 12:41:05 +02:00
										 |  |  |             ydl.cache.remove() | 
					
						
							| 
									
										
										
										
											2014-07-24 12:16:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |         # Maybe do nothing | 
					
						
							| 
									
										
										
										
											2013-11-22 14:57:53 +01:00
										 |  |  |         if (len(all_urls) < 1) and (opts.load_info_filename is None): | 
					
						
							| 
									
										
										
										
											2014-11-23 10:49:19 +01:00
										 |  |  |             if opts.update_self or opts.rm_cachedir: | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |                 sys.exit() | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-23 10:49:19 +01:00
										 |  |  |             ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv) | 
					
						
							|  |  |  |             parser.error('you must provide at least one URL') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-11-22 14:57:53 +01:00
										 |  |  |             if opts.load_info_filename is not None: | 
					
						
							|  |  |  |                 retcode = ydl.download_with_info_file(opts.load_info_filename) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 retcode = ydl.download(all_urls) | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |         except MaxDownloadsReached: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |             ydl.to_screen('--max-download limit reached, aborting.') | 
					
						
							| 
									
										
										
										
											2013-11-17 21:05:14 +01:00
										 |  |  |             retcode = 101 | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     sys.exit(retcode) | 
					
						
							| 
									
										
										
										
											2011-11-21 19:59:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-07 18:50:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-16 19:26:48 +02:00
										 |  |  | def main(argv=None): | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2013-04-16 19:26:48 +02:00
										 |  |  |         _real_main(argv) | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     except DownloadError: | 
					
						
							|  |  |  |         sys.exit(1) | 
					
						
							|  |  |  |     except SameFileError: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         sys.exit('ERROR: fixed output name but more than one file to download') | 
					
						
							| 
									
										
										
										
											2012-11-28 02:04:46 +01:00
										 |  |  |     except KeyboardInterrupt: | 
					
						
							| 
									
										
										
										
											2014-11-16 15:08:34 +01:00
										 |  |  |         sys.exit('\nERROR: Interrupted by user') |