2011-11-21 19:59:59 +01:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
2012-01-05 00:36:47 +01:00
__authors__ = (
2012-11-28 02:04:46 +01:00
' Ricardo Garcia Gonzalez ' ,
' Danny Colligan ' ,
' Benjamin Johnson ' ,
' Vasyl \' Vavrychuk ' ,
' Witold Baryluk ' ,
' Paweł Paprota ' ,
' Gergely Imreh ' ,
' Rogério Brito ' ,
' Philipp Hagemeister ' ,
' Sören Schulze ' ,
' Kevin Ngo ' ,
' Ori Avtalion ' ,
' shizeeg ' ,
' Filippo Valsorda ' ,
' Christian Albrecht ' ,
2012-12-16 11:16:57 +01:00
' Dave Vasilevsky ' ,
2013-01-01 18:29:43 +01:00
' Jaime Marquínez Ferrándiz ' ,
2013-01-12 16:51:20 +01:00
' Jeff Crouse ' ,
2013-02-08 11:01:09 +01:00
' Osama Khalid ' ,
2013-04-11 10:48:37 +02:00
' Michael Walter ' ,
2013-05-03 20:08:16 +02:00
' M. Yasoob Ullah Khalid ' ,
2013-05-05 21:35:39 +02:00
' Julien Fraichard ' ,
2013-05-05 21:56:38 +02:00
' Johny Mo Swag ' ,
2013-06-25 17:57:47 +02:00
' Axel Noack ' ,
2013-06-27 20:50:34 +02:00
' Albert Kim ' ,
2013-08-22 13:21:32 +02:00
' Pierre Rudloff ' ,
2013-09-04 22:09:22 +02:00
' Huarong Huo ' ,
2013-09-11 17:58:51 +02:00
' Ismael Mejía ' ,
2013-09-18 22:30:22 +02:00
' Steffan \' Ruirize \' James ' ,
2013-10-15 01:34:47 +02:00
' Andras Elso ' ,
2013-11-13 10:52:22 +01:00
' Jelle van der Waa ' ,
2013-11-13 11:08:07 +01:00
' Marcin Cieślak ' ,
2013-11-20 06:36:00 +01:00
' Anton Larionov ' ,
2013-11-24 06:39:49 +01:00
' Takuya Tsuchida ' ,
2013-12-02 17:43:22 +01:00
' Sergey M. ' ,
2013-12-16 05:11:19 +01:00
' Michael Orlitzky ' ,
2014-01-02 13:47:28 +01:00
' Chris Gahan ' ,
2014-01-17 03:09:34 +01:00
' Saimadhav Heblikar ' ,
2014-01-27 07:43:41 +01:00
' Mike Col ' ,
2014-02-17 03:03:28 +01:00
' Oleg Prutz ' ,
2014-02-17 03:07:36 +01:00
' pulpe ' ,
2014-02-07 12:00:58 +01:00
' Andreas Schmitz ' ,
2014-02-17 03:08:38 +01:00
' Michael Kaiser ' ,
2014-02-17 11:33:01 +01:00
' Niklas Laxström ' ,
2014-02-22 20:19:41 +01:00
' David Triendl ' ,
2014-02-26 00:30:47 +01:00
' Anthony Weems ' ,
2014-02-28 15:14:25 +01:00
' David Wagner ' ,
2014-03-03 12:54:01 +01:00
' Juan C. Olivares ' ,
2014-03-10 10:30:17 +01:00
' Mattias Harrysson ' ,
2014-03-29 10:11:32 +01:00
' phaer ' ,
2014-04-05 10:53:50 +02:00
' Sainyam Kapoor ' ,
2014-05-01 21:36:11 +02:00
' Nicolas Évrard ' ,
2014-05-13 09:53:58 +02:00
' Jason Normore ' ,
2014-05-13 10:00:27 +02:00
' Hoje Lee ' ,
2014-05-20 15:12:57 +02:00
' Adam Thalhammer ' ,
2014-06-07 15:40:27 +02:00
' Georg Jähnig ' ,
2014-06-07 16:41:44 +02:00
' Ralf Haring ' ,
2014-07-04 17:30:43 +02:00
' Koki Takahashi ' ,
2014-07-11 11:11:52 +02:00
' Ariset Llerena ' ,
2014-07-11 11:16:04 +02:00
' Adam Malcontenti-Wilson ' ,
2014-07-11 11:29:17 +02:00
' Tobias Bell ' ,
2014-07-12 14:23:54 +02:00
' Naglis Jonaitis ' ,
2014-07-16 16:03:30 +02:00
' Charles Chen ' ,
2014-07-18 16:41:34 +02:00
' Hassaan Ali ' ,
2014-08-05 14:09:11 +02:00
' Dobrosław Żybort ' ,
2013-06-27 20:50:34 +02:00
)
2011-11-21 19:59:59 +01:00
__license__ = ' Public Domain '
2013-05-04 07:09:50 +02:00
import codecs
2014-02-25 23:31:16 +01:00
import io
2012-02-26 23:53:56 +01:00
import optparse
2011-11-21 19:59:59 +01:00
import os
2013-07-01 18:52:19 +02:00
import random
2012-02-26 23:53:56 +01:00
import shlex
2014-07-24 12:16:16 +02:00
import shutil
2011-11-21 19:59:59 +01:00
import sys
2013-08-28 12:57:10 +02:00
2013-10-15 02:07:26 +02:00
from . utils import (
2014-03-18 14:27:42 +01:00
compat_getpass ,
2013-10-15 02:07:26 +02:00
compat_print ,
DateRange ,
2014-04-30 10:02:03 +02:00
DEFAULT_OUTTMPL ,
2013-10-15 02:07:26 +02:00
decodeOption ,
2013-12-09 18:29:07 +01:00
get_term_width ,
2013-10-15 02:07:26 +02:00
DownloadError ,
get_cachedir ,
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-11-22 19:57:52 +01:00
from . version import __version__
2013-06-18 22:14:21 +02:00
from . YoutubeDL import YoutubeDL
2014-01-07 05:49:17 +01:00
from . postprocessor import (
2014-02-22 13:55:51 +01:00
AtomicParsleyPP ,
2014-02-22 18:10:07 +01:00
FFmpegAudioFixPP ,
2013-10-15 02:07:26 +02:00
FFmpegMetadataPP ,
FFmpegVideoConvertor ,
FFmpegExtractAudioPP ,
FFmpegEmbedSubtitlePP ,
2014-01-02 13:47:28 +01:00
XAttrMetadataPP ,
2013-10-15 02:07:26 +02:00
)
2011-11-21 19:59:59 +01:00
2013-04-22 23:05:05 +02:00
def parseOpts ( overrideArguments = None ) :
2013-12-03 13:09:48 +01:00
def _readOptions ( filename_bytes , default = [ ] ) :
2012-11-28 02:04:46 +01:00
try :
optionf = open ( filename_bytes )
except IOError :
2013-12-03 13:09:48 +01:00
return default # silently skip if file is not present
2012-11-28 02:04:46 +01:00
try :
2013-12-03 13:11:20 +01:00
res = [ ]
for l in optionf :
res + = shlex . split ( l , comments = True )
2012-11-28 02:04:46 +01:00
finally :
optionf . close ( )
return res
2014-02-03 06:54:27 +01:00
def _readUserConf ( ) :
xdg_config_home = os . environ . get ( ' XDG_CONFIG_HOME ' )
if xdg_config_home :
userConfFile = os . path . join ( xdg_config_home , ' youtube-dl ' , ' config ' )
if not os . path . isfile ( userConfFile ) :
userConfFile = os . path . join ( xdg_config_home , ' youtube-dl.conf ' )
else :
userConfFile = os . path . join ( os . path . expanduser ( ' ~ ' ) , ' .config ' , ' youtube-dl ' , ' config ' )
if not os . path . isfile ( userConfFile ) :
userConfFile = os . path . join ( os . path . expanduser ( ' ~ ' ) , ' .config ' , ' youtube-dl.conf ' )
userConf = _readOptions ( userConfFile , None )
if userConf is None :
appdata_dir = os . environ . get ( ' appdata ' )
if appdata_dir :
userConf = _readOptions (
os . path . join ( appdata_dir , ' youtube-dl ' , ' config ' ) ,
default = None )
if userConf is None :
userConf = _readOptions (
os . path . join ( appdata_dir , ' youtube-dl ' , ' config.txt ' ) ,
default = None )
if userConf is None :
userConf = _readOptions (
os . path . join ( os . path . expanduser ( ' ~ ' ) , ' youtube-dl.conf ' ) ,
default = None )
if userConf is None :
userConf = _readOptions (
os . path . join ( os . path . expanduser ( ' ~ ' ) , ' youtube-dl.conf.txt ' ) ,
default = None )
if userConf is None :
userConf = [ ]
return userConf
2012-11-28 02:04:46 +01:00
def _format_option_string ( option ) :
''' ( ' -o ' , ' --option ' ) -> -o, --format METAVAR '''
opts = [ ]
if option . _short_opts :
opts . append ( option . _short_opts [ 0 ] )
if option . _long_opts :
opts . append ( option . _long_opts [ 0 ] )
if len ( opts ) > 1 :
opts . insert ( 1 , ' , ' )
if option . takes_value ( ) : opts . append ( ' %s ' % option . metavar )
return " " . join ( opts )
2013-09-06 16:26:22 +02:00
def _comma_separated_values_options_callback ( option , opt_str , value , parser ) :
setattr ( parser . values , option . dest , value . split ( ' , ' ) )
2013-07-20 12:49:24 +02:00
def _hide_login_info ( opts ) :
opts = list ( opts )
2013-10-23 16:32:17 +02:00
for private_opt in [ ' -p ' , ' --password ' , ' -u ' , ' --username ' , ' --video-password ' ] :
2013-07-20 12:49:24 +02:00
try :
i = opts . index ( private_opt )
opts [ i + 1 ] = ' <PRIVATE> '
except ValueError :
pass
return opts
2012-11-28 02:04:46 +01:00
max_width = 80
max_help_position = 80
# No need to wrap help messages if we're on a wide console
2013-12-09 18:29:07 +01:00
columns = get_term_width ( )
2012-11-28 02:04:46 +01:00
if columns : max_width = columns
fmt = optparse . IndentedHelpFormatter ( width = max_width , max_help_position = max_help_position )
fmt . format_option_strings = _format_option_string
kw = {
' version ' : __version__ ,
' formatter ' : fmt ,
' usage ' : ' % prog [options] url [url...] ' ,
' conflict_handler ' : ' resolve ' ,
}
parser = optparse . OptionParser ( * * kw )
# option groups
general = optparse . OptionGroup ( parser , ' General Options ' )
selection = optparse . OptionGroup ( parser , ' Video Selection ' )
authentication = optparse . OptionGroup ( parser , ' Authentication Options ' )
video_format = optparse . OptionGroup ( parser , ' Video Format Options ' )
2013-08-08 09:53:25 +02:00
subtitles = optparse . OptionGroup ( parser , ' Subtitle Options ' )
2013-07-01 14:53:25 +02:00
downloader = optparse . OptionGroup ( parser , ' Download Options ' )
2012-11-28 02:04:46 +01:00
postproc = optparse . OptionGroup ( parser , ' Post-processing Options ' )
filesystem = optparse . OptionGroup ( parser , ' Filesystem Options ' )
2014-07-24 11:46:21 +02:00
workarounds = optparse . OptionGroup ( parser , ' Workarounds ' )
2012-11-28 02:04:46 +01:00
verbosity = optparse . OptionGroup ( parser , ' Verbosity / Simulation Options ' )
general . add_option ( ' -h ' , ' --help ' ,
action = ' help ' , help = ' print this help text and exit ' )
general . add_option ( ' -v ' , ' --version ' ,
action = ' version ' , help = ' print program version and exit ' )
general . add_option ( ' -U ' , ' --update ' ,
2013-07-18 12:53:24 +02:00
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) ' )
2012-11-28 02:04:46 +01:00
general . add_option ( ' -i ' , ' --ignore-errors ' ,
2014-02-20 04:02:29 +01:00
action = ' store_true ' , dest = ' ignoreerrors ' , help = ' continue on download errors, for example to skip unavailable videos in a playlist ' , default = False )
2013-10-18 23:09:32 +02:00
general . add_option ( ' --abort-on-error ' ,
action = ' store_false ' , dest = ' ignoreerrors ' ,
help = ' Abort downloading of further videos (in the playlist or the command line) if an error occurs ' )
2012-11-28 02:04:46 +01:00
general . add_option ( ' --dump-user-agent ' ,
action = ' store_true ' , dest = ' dump_user_agent ' ,
help = ' display the current browser identification ' , default = False )
general . add_option ( ' --list-extractors ' ,
action = ' store_true ' , dest = ' list_extractors ' ,
help = ' List all supported extractors and the URLs they would handle ' , default = False )
2013-07-01 18:59:29 +02:00
general . add_option ( ' --extractor-descriptions ' ,
2013-07-01 18:52:19 +02:00
action = ' store_true ' , dest = ' list_extractor_descriptions ' ,
help = ' Output descriptions of all supported extractors ' , default = False )
2013-12-03 13:33:07 +01:00
general . add_option (
' --proxy ' , dest = ' proxy ' , default = None , metavar = ' URL ' ,
help = ' Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy " " ) for direct connection ' )
2013-12-02 13:37:05 +01:00
general . add_option (
' --socket-timeout ' , dest = ' socket_timeout ' ,
2014-01-05 04:36:46 +01:00
type = float , default = None , help = u ' Time to wait before giving up, in seconds ' )
2014-03-30 15:57:31 +02:00
general . add_option (
' --default-search ' ,
dest = ' default_search ' , metavar = ' PREFIX ' ,
2014-07-29 17:17:43 +02:00
help = ' Use this prefix for unqualified URLs. For example " gvsearch2: " downloads two videos from google videos for youtube-dl " large apple " . Use the value " auto " to let youtube-dl guess ( " auto_warning " to emit a warning when guessing). " error " just throws an error. The default value " fixup_error " repairs broken URLs, but emits an error if this is not possible instead of searching. ' )
2014-02-03 06:54:27 +01:00
general . add_option (
' --ignore-config ' ,
action = ' store_true ' ,
help = ' Do not read configuration files. When given in the global configuration file /etc/youtube-dl.conf: do not read the user configuration in ~/.config/youtube-dl.conf ( % APPDATA % /youtube-dl/config.txt on Windows) ' )
2013-12-16 13:16:20 +01:00
selection . add_option (
' --playlist-start ' ,
dest = ' playliststart ' , metavar = ' NUMBER ' , default = 1 , type = int ,
help = ' playlist video to start at (default is %d efault) ' )
selection . add_option (
' --playlist-end ' ,
dest = ' playlistend ' , metavar = ' NUMBER ' , default = None , type = int ,
help = ' playlist video to end at (default is last) ' )
2012-11-28 02:04:46 +01:00
selection . add_option ( ' --match-title ' , dest = ' matchtitle ' , metavar = ' REGEX ' , help = ' download only matching titles (regex or caseless sub-string) ' )
selection . add_option ( ' --reject-title ' , dest = ' rejecttitle ' , metavar = ' REGEX ' , help = ' skip download for matching titles (regex or caseless sub-string) ' )
2013-11-25 22:15:20 +01:00
selection . add_option ( ' --max-downloads ' , metavar = ' NUMBER ' ,
dest = ' max_downloads ' , type = int , default = None ,
help = ' Abort after downloading NUMBER files ' )
2013-02-02 14:44:22 +01:00
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 )
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 )
2013-04-27 14:01:55 +02:00
selection . add_option ( ' --date ' , metavar = ' DATE ' , dest = ' date ' , help = ' download only videos uploaded in this date ' , default = None )
2014-01-07 10:09:37 +01:00
selection . add_option (
' --datebefore ' , metavar = ' DATE ' , dest = ' datebefore ' , default = None ,
help = ' download only videos uploaded on or before this date (i.e. inclusive) ' )
selection . add_option (
' --dateafter ' , metavar = ' DATE ' , dest = ' dateafter ' , default = None ,
help = ' download only videos uploaded on or after this date (i.e. inclusive) ' )
2013-12-16 03:09:49 +01:00
selection . add_option (
' --min-views ' , metavar = ' COUNT ' , dest = ' min_views ' ,
default = None , type = int ,
help = " Do not download any videos with less than COUNT views " , )
selection . add_option (
' --max-views ' , metavar = ' COUNT ' , dest = ' max_views ' ,
default = None , type = int ,
help = " Do not download any videos with more than COUNT views " , )
2013-09-30 22:26:25 +02:00
selection . add_option ( ' --no-playlist ' , action = ' store_true ' , dest = ' noplaylist ' , help = ' download only the currently playing video ' , default = False )
2013-10-06 06:06:30 +02:00
selection . add_option ( ' --age-limit ' , metavar = ' YEARS ' , dest = ' age_limit ' ,
help = ' download only videos suitable for the given age ' ,
default = None , type = int )
2013-10-06 04:27:09 +02:00
selection . add_option ( ' --download-archive ' , metavar = ' FILE ' ,
dest = ' download_archive ' ,
2013-12-03 11:54:52 +01:00
help = ' Download only videos not listed in the archive file. Record the IDs of all downloaded videos in it. ' )
2014-01-21 02:09:49 +01:00
selection . add_option (
' --include-ads ' , dest = ' include_ads ' ,
action = ' store_true ' ,
help = ' Download advertisements as well (experimental) ' )
2014-01-22 22:17:53 +01:00
selection . add_option (
2014-01-22 21:56:37 +01:00
' --youtube-include-dash-manifest ' , action = ' store_true ' ,
dest = ' youtube_include_dash_manifest ' , default = False ,
help = ' Try to download the DASH manifest on YouTube videos (experimental) ' )
2013-01-22 06:50:42 +01:00
2012-11-28 02:04:46 +01:00
authentication . add_option ( ' -u ' , ' --username ' ,
dest = ' username ' , metavar = ' USERNAME ' , help = ' account username ' )
authentication . add_option ( ' -p ' , ' --password ' ,
dest = ' password ' , metavar = ' PASSWORD ' , help = ' account password ' )
authentication . add_option ( ' -n ' , ' --netrc ' ,
action = ' store_true ' , dest = ' usenetrc ' , help = ' use .netrc authentication data ' , default = False )
2013-06-25 22:22:32 +02:00
authentication . add_option ( ' --video-password ' ,
2014-01-12 00:27:00 +01:00
dest = ' videopassword ' , metavar = ' PASSWORD ' , help = ' video password (vimeo, smotri) ' )
2012-11-28 02:04:46 +01:00
video_format . add_option ( ' -f ' , ' --format ' ,
2014-01-22 14:53:23 +01:00
action = ' store ' , dest = ' format ' , metavar = ' FORMAT ' , default = None ,
2014-03-14 17:01:47 +01:00
help = ' video format code, specify the order of preference using slashes: " -f 22/17/18 " . " -f mp4 " and " -f flv " are also supported. You can also use the special names " best " , " bestvideo " , " bestaudio " , " worst " , " worstvideo " and " worstaudio " . By default, youtube-dl will pick the best quality. ' )
2012-11-28 02:04:46 +01:00
video_format . add_option ( ' --all-formats ' ,
action = ' store_const ' , dest = ' format ' , help = ' download all available video formats ' , const = ' all ' )
video_format . add_option ( ' --prefer-free-formats ' ,
action = ' store_true ' , dest = ' prefer_free_formats ' , default = False , help = ' prefer free video formats unless a specific one is requested ' )
video_format . add_option ( ' --max-quality ' ,
action = ' store ' , dest = ' format_limit ' , metavar = ' FORMAT ' , help = ' highest quality format to download ' )
video_format . add_option ( ' -F ' , ' --list-formats ' ,
2014-01-13 00:03:31 +01:00
action = ' store_true ' , dest = ' listformats ' , help = ' list all available formats ' )
2013-08-08 09:53:25 +02:00
subtitles . add_option ( ' --write-sub ' , ' --write-srt ' ,
2012-11-28 02:04:46 +01:00
action = ' store_true ' , dest = ' writesubtitles ' ,
2013-08-07 18:59:11 +02:00
help = ' write subtitle file ' , default = False )
2013-08-08 09:53:25 +02:00
subtitles . add_option ( ' --write-auto-sub ' , ' --write-automatic-sub ' ,
2013-06-25 23:45:16 +02:00
action = ' store_true ' , dest = ' writeautomaticsub ' ,
2013-08-07 18:59:11 +02:00
help = ' write automatic subtitle file (youtube only) ' , default = False )
2013-08-08 09:53:25 +02:00
subtitles . add_option ( ' --all-subs ' ,
2013-02-22 02:52:55 +01:00
action = ' store_true ' , dest = ' allsubtitles ' ,
2013-08-07 18:59:11 +02:00
help = ' downloads all the available subtitles of the video ' , default = False )
2013-08-08 09:53:25 +02:00
subtitles . add_option ( ' --list-subs ' ,
2013-02-22 04:50:05 +01:00
action = ' store_true ' , dest = ' listsubtitles ' ,
2013-08-07 18:59:11 +02:00
help = ' lists all available subtitles for the video ' , default = False )
2013-08-08 09:53:25 +02:00
subtitles . add_option ( ' --sub-format ' ,
2013-06-23 12:59:20 +02:00
action = ' store ' , dest = ' subtitlesformat ' , metavar = ' FORMAT ' ,
2013-08-07 18:59:11 +02:00
help = ' subtitle format (default=srt) ([sbv/vtt] youtube only) ' , default = ' srt ' )
2013-09-06 16:26:22 +02:00
subtitles . add_option ( ' --sub-lang ' , ' --sub-langs ' , ' --srt-lang ' ,
action = ' callback ' , dest = ' subtitleslangs ' , metavar = ' LANGS ' , type = ' str ' ,
default = [ ] , callback = _comma_separated_values_options_callback ,
help = ' languages of the subtitles to download (optional) separated by commas, use IETF language tags like \' en,pt \' ' )
2012-11-28 02:04:46 +01:00
2013-07-01 14:53:25 +02:00
downloader . add_option ( ' -r ' , ' --rate-limit ' ,
2013-10-15 04:53:02 +02:00
dest = ' ratelimit ' , metavar = ' LIMIT ' , help = ' maximum download rate in bytes per second (e.g. 50K or 4.2M) ' )
2014-08-03 16:34:04 +02:00
downloader . add_option ( ' --sleep-interval ' ,
dest = ' sleepinterval ' , metavar = ' SLEEPINTERVAL ' , help = ' number of seconds to sleep between downloads (default is %d efault) ' , default = " 0 " )
2013-07-01 14:53:25 +02:00
downloader . add_option ( ' -R ' , ' --retries ' ,
dest = ' retries ' , metavar = ' RETRIES ' , help = ' number of retries (default is %d efault) ' , default = 10 )
downloader . add_option ( ' --buffer-size ' ,
2013-10-15 04:53:02 +02:00
dest = ' buffersize ' , metavar = ' SIZE ' , help = ' size of download buffer (e.g. 1024 or 16K) (default is %d efault) ' , default = " 1024 " )
2013-07-01 14:53:25 +02:00
downloader . add_option ( ' --no-resize-buffer ' ,
action = ' store_true ' , dest = ' noresizebuffer ' ,
help = ' do not automatically adjust the buffer size. By default, the buffer size is automatically resized from an initial value of SIZE. ' , default = False )
downloader . add_option ( ' --test ' , action = ' store_true ' , dest = ' test ' , default = False , help = optparse . SUPPRESS_HELP )
2014-07-24 11:46:21 +02:00
workarounds . add_option (
' --encoding ' , dest = ' encoding ' , metavar = ' ENCODING ' ,
help = ' Force the specified encoding (experimental) ' )
workarounds . add_option (
' --no-check-certificate ' , action = ' store_true ' ,
dest = ' no_check_certificate ' , default = False ,
help = ' Suppress HTTPS certificate validation. ' )
workarounds . add_option (
' --prefer-insecure ' , ' --prefer-unsecure ' , action = ' store_true ' , dest = ' prefer_insecure ' ,
help = ' Use an unencrypted connection to retrieve information about the video. (Currently supported only for YouTube) ' )
workarounds . add_option (
' --user-agent ' , metavar = ' UA ' ,
dest = ' user_agent ' , help = ' specify a custom user agent ' )
workarounds . add_option (
' --referer ' , metavar = ' REF ' ,
dest = ' referer ' , default = None ,
help = ' specify a custom referer, use if the video access is restricted to one domain ' ,
)
workarounds . add_option (
' --add-header ' , metavar = ' FIELD:VALUE ' ,
dest = ' headers ' , action = ' append ' ,
help = ' specify a custom HTTP header and its value, separated by a colon \' : \' . You can use this option multiple times ' ,
)
2014-07-29 17:19:07 +02:00
workarounds . add_option (
' --bidi-workaround ' , dest = ' bidi_workaround ' , action = ' store_true ' ,
help = u ' Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH ' )
2014-07-24 11:46:21 +02:00
2012-11-28 02:04:46 +01:00
verbosity . add_option ( ' -q ' , ' --quiet ' ,
action = ' store_true ' , dest = ' quiet ' , help = ' activates quiet mode ' , default = False )
2014-03-26 00:43:46 +01:00
verbosity . add_option (
' --no-warnings ' ,
dest = ' no_warnings ' , action = ' store_true ' , default = False ,
help = ' Ignore warnings ' )
2012-11-28 02:04:46 +01:00
verbosity . add_option ( ' -s ' , ' --simulate ' ,
action = ' store_true ' , dest = ' simulate ' , help = ' do not download the video and do not write anything to disk ' , default = False )
verbosity . add_option ( ' --skip-download ' ,
action = ' store_true ' , dest = ' skip_download ' , help = ' do not download the video ' , default = False )
verbosity . add_option ( ' -g ' , ' --get-url ' ,
action = ' store_true ' , dest = ' geturl ' , help = ' simulate, quiet but print URL ' , default = False )
verbosity . add_option ( ' -e ' , ' --get-title ' ,
action = ' store_true ' , dest = ' gettitle ' , help = ' simulate, quiet but print title ' , default = False )
2013-05-06 07:30:07 +02:00
verbosity . add_option ( ' --get-id ' ,
action = ' store_true ' , dest = ' getid ' , help = ' simulate, quiet but print id ' , default = False )
2012-11-28 02:04:46 +01:00
verbosity . add_option ( ' --get-thumbnail ' ,
action = ' store_true ' , dest = ' getthumbnail ' ,
help = ' simulate, quiet but print thumbnail URL ' , default = False )
verbosity . add_option ( ' --get-description ' ,
action = ' store_true ' , dest = ' getdescription ' ,
help = ' simulate, quiet but print video description ' , default = False )
2013-12-16 04:15:10 +01:00
verbosity . add_option ( ' --get-duration ' ,
action = ' store_true ' , dest = ' getduration ' ,
help = ' simulate, quiet but print video length ' , default = False )
2012-11-28 02:04:46 +01:00
verbosity . add_option ( ' --get-filename ' ,
action = ' store_true ' , dest = ' getfilename ' ,
help = ' simulate, quiet but print output filename ' , default = False )
verbosity . add_option ( ' --get-format ' ,
action = ' store_true ' , dest = ' getformat ' ,
help = ' simulate, quiet but print output format ' , default = False )
2013-11-19 14:59:22 +01:00
verbosity . add_option ( ' -j ' , ' --dump-json ' ,
action = ' store_true ' , dest = ' dumpjson ' ,
2014-03-28 23:13:03 +01:00
help = ' simulate, quiet but print JSON information. See --output for a description of available keys. ' , default = False )
2013-02-13 02:02:31 +01:00
verbosity . add_option ( ' --newline ' ,
2013-02-18 18:52:06 +01:00
action = ' store_true ' , dest = ' progress_with_newline ' , help = ' output progress bar as new lines ' , default = False )
2012-11-28 02:04:46 +01:00
verbosity . add_option ( ' --no-progress ' ,
action = ' store_true ' , dest = ' noprogress ' , help = ' do not print progress bar ' , default = False )
verbosity . add_option ( ' --console-title ' ,
action = ' store_true ' , dest = ' consoletitle ' ,
help = ' display progress in console titlebar ' , default = False )
verbosity . add_option ( ' -v ' , ' --verbose ' ,
action = ' store_true ' , dest = ' verbose ' , help = ' print various debugging information ' , default = False )
2013-04-11 18:31:35 +02:00
verbosity . add_option ( ' --dump-intermediate-pages ' ,
action = ' store_true ' , dest = ' dump_intermediate_pages ' , default = False ,
2014-01-12 00:27:00 +01:00
help = ' print downloaded pages to debug problems (very verbose) ' )
2013-10-28 10:44:02 +01:00
verbosity . add_option ( ' --write-pages ' ,
action = ' store_true ' , dest = ' write_pages ' , default = False ,
2013-11-30 00:42:43 +01:00
help = ' Write downloaded intermediary pages to files in the current directory to debug problems ' )
2013-09-22 10:30:02 +02:00
verbosity . add_option ( ' --youtube-print-sig-code ' ,
action = ' store_true ' , dest = ' youtube_print_sig_code ' , default = False ,
help = optparse . SUPPRESS_HELP )
2013-12-29 15:28:32 +01:00
verbosity . add_option ( ' --print-traffic ' ,
dest = ' debug_printtraffic ' , action = ' store_true ' , default = False ,
2014-01-22 21:56:37 +01:00
help = ' Display sent and read HTTP traffic ' )
2012-11-28 02:04:46 +01:00
2014-07-24 11:50:49 +02:00
filesystem . add_option ( ' -a ' , ' --batch-file ' ,
dest = ' batchfile ' , metavar = ' FILE ' , help = ' file containing URLs to download ( \' - \' for stdin) ' )
2012-11-28 02:04:46 +01:00
filesystem . add_option ( ' --id ' ,
2013-04-28 16:26:11 +02:00
action = ' store_true ' , dest = ' useid ' , help = ' use only video ID in file name ' , default = False )
2012-11-28 02:04:46 +01:00
filesystem . add_option ( ' -A ' , ' --auto-number ' ,
action = ' store_true ' , dest = ' autonumber ' ,
help = ' number downloaded files starting from 00000 ' , default = False )
filesystem . add_option ( ' -o ' , ' --output ' ,
2013-04-22 10:06:07 +02:00
dest = ' outtmpl ' , metavar = ' TEMPLATE ' ,
help = ( ' output filename template. Use %(title)s to get the title, '
' %(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, '
' %(autonumber)s to get an automatically incremented number, '
2013-10-18 23:06:49 +02:00
' %(ext)s for the filename extension, '
2014-01-12 00:27:00 +01:00
' %(format)s for the format description (like " 22 - 1280x720 " or " HD " ), '
' %(format_id)s for the unique id of the format (like Youtube \' s itags: " 137 " ), '
2013-10-18 23:06:49 +02:00
' %(upload_date)s for the upload date (YYYYMMDD), '
2013-04-22 10:06:07 +02:00
' %(extractor)s for the provider (youtube, metacafe, etc), '
2014-01-12 00:27:00 +01:00
' %(id)s for the video id, %(playlist)s for the playlist the video is in, '
2013-04-22 10:06:07 +02:00
' %(playlist_index)s for the position in the playlist and %% for a literal percent. '
2014-03-04 03:49:33 +01:00
' %(height)s and %(width)s for the width and height of the video format. '
' %(resolution)s for a textual description of the resolution of the video format. '
2013-04-22 10:06:07 +02:00
' Use - to output to stdout. Can also be used to download to a different directory, '
' for example with -o \' /my/downloads/ %(uploader)s / %(title)s - %(id)s . %(ext)s \' . ' ) )
2013-04-02 06:40:07 +02:00
filesystem . add_option ( ' --autonumber-size ' ,
dest = ' autonumber_size ' , metavar = ' NUMBER ' ,
2013-11-09 19:21:30 +01:00
help = ' Specifies the number of digits in %(autonumber)s when it is present in output filename template or --auto-number option is given ' )
2012-11-28 02:04:46 +01:00
filesystem . add_option ( ' --restrict-filenames ' ,
action = ' store_true ' , dest = ' restrictfilenames ' ,
help = ' Restrict filenames to only ASCII characters, and avoid " & " and spaces in filenames ' , default = False )
2014-07-24 11:50:49 +02:00
filesystem . add_option ( ' -t ' , ' --title ' ,
2014-07-24 11:52:16 +02:00
action = ' store_true ' , dest = ' usetitle ' , help = ' [deprecated] use title in file name (default) ' , default = False )
2014-07-24 11:50:49 +02:00
filesystem . add_option ( ' -l ' , ' --literal ' ,
action = ' store_true ' , dest = ' usetitle ' , help = ' [deprecated] alias of --title ' , default = False )
2012-11-28 02:04:46 +01:00
filesystem . add_option ( ' -w ' , ' --no-overwrites ' ,
action = ' store_true ' , dest = ' nooverwrites ' , help = ' do not overwrite files ' , default = False )
filesystem . add_option ( ' -c ' , ' --continue ' ,
2013-11-11 14:21:09 +01:00
action = ' store_true ' , dest = ' continue_dl ' , help = ' force resume of partially downloaded files. By default, youtube-dl will resume downloads if possible. ' , default = True )
2012-11-28 02:04:46 +01:00
filesystem . add_option ( ' --no-continue ' ,
action = ' store_false ' , dest = ' continue_dl ' ,
help = ' do not resume partially downloaded files (restart from beginning) ' )
filesystem . add_option ( ' --no-part ' ,
action = ' store_true ' , dest = ' nopart ' , help = ' do not use .part files ' , default = False )
filesystem . add_option ( ' --no-mtime ' ,
action = ' store_false ' , dest = ' updatetime ' ,
help = ' do not use the Last-modified header to set the file modification time ' , default = True )
filesystem . add_option ( ' --write-description ' ,
action = ' store_true ' , dest = ' writedescription ' ,
help = ' write video description to a .description file ' , default = False )
filesystem . add_option ( ' --write-info-json ' ,
action = ' store_true ' , dest = ' writeinfojson ' ,
help = ' write video metadata to a .info.json file ' , default = False )
2013-10-14 07:18:58 +02:00
filesystem . add_option ( ' --write-annotations ' ,
action = ' store_true ' , dest = ' writeannotations ' ,
help = ' write video annotations to a .annotation file ' , default = False )
2013-05-01 14:04:33 +02:00
filesystem . add_option ( ' --write-thumbnail ' ,
action = ' store_true ' , dest = ' writethumbnail ' ,
help = ' write thumbnail image to disk ' , default = False )
2014-07-24 11:50:49 +02:00
filesystem . add_option ( ' --load-info ' ,
dest = ' load_info_filename ' , metavar = ' FILE ' ,
help = ' json file containing the video information (created with the " --write-json " option) ' )
filesystem . add_option ( ' --cookies ' ,
dest = ' cookiefile ' , metavar = ' FILE ' , help = ' file to read cookies from and dump cookie jar in ' )
2014-07-24 11:49:26 +02:00
filesystem . add_option (
' --cache-dir ' , dest = ' cachedir ' , default = get_cachedir ( ) , metavar = ' DIR ' ,
help = ' Location in the filesystem where youtube-dl can store some downloaded information permanently. By default $XDG_CACHE_HOME/youtube-dl or ~/.cache/youtube-dl . At the moment, only YouTube player files (for videos with obfuscated signatures) are cached, but that may change. ' )
filesystem . add_option (
' --no-cache-dir ' , action = ' store_const ' , const = None , dest = ' cachedir ' ,
help = ' Disable filesystem caching ' )
2014-07-24 12:16:16 +02:00
filesystem . add_option (
' --rm-cache-dir ' , action = ' store_true ' , dest = ' rm_cachedir ' ,
help = ' Delete all filesystem cache files ' )
2012-11-28 02:04:46 +01:00
postproc . add_option ( ' -x ' , ' --extract-audio ' , action = ' store_true ' , dest = ' extractaudio ' , default = False ,
help = ' convert video files to audio-only files (requires ffmpeg or avconv and ffprobe or avprobe) ' )
postproc . add_option ( ' --audio-format ' , metavar = ' FORMAT ' , dest = ' audioformat ' , default = ' best ' ,
2013-01-10 19:15:04 +01:00
help = ' " best " , " aac " , " vorbis " , " mp3 " , " m4a " , " opus " , or " wav " ; best by default ' )
2012-11-28 02:04:46 +01:00
postproc . add_option ( ' --audio-quality ' , metavar = ' QUALITY ' , dest = ' audioquality ' , default = ' 5 ' ,
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) ' )
2013-01-12 15:07:59 +01:00
postproc . add_option ( ' --recode-video ' , metavar = ' FORMAT ' , dest = ' recodevideo ' , default = None ,
2014-07-11 16:16:30 +02:00
help = ' Encode the video to another format if necessary (currently supported: mp4|flv|ogg|webm|mkv) ' )
2012-11-28 02:04:46 +01:00
postproc . add_option ( ' -k ' , ' --keep-video ' , action = ' store_true ' , dest = ' keepvideo ' , default = False ,
help = ' keeps the video file on disk after the post-processing; the video is erased by default ' )
2012-12-23 18:36:48 +01:00
postproc . add_option ( ' --no-post-overwrites ' , action = ' store_true ' , dest = ' nopostoverwrites ' , default = False ,
help = ' do not overwrite post-processed files; the post-processed files are overwritten by default ' )
2013-07-20 12:48:57 +02:00
postproc . add_option ( ' --embed-subs ' , action = ' store_true ' , dest = ' embedsubtitles ' , default = False ,
help = ' embed subtitles in the video (only for mp4 videos) ' )
2014-02-22 13:55:51 +01:00
postproc . add_option ( ' --embed-thumbnail ' , action = ' store_true ' , dest = ' embedthumbnail ' , default = False ,
help = ' embed thumbnail in the audio as cover art ' )
2013-10-11 11:19:09 +02:00
postproc . add_option ( ' --add-metadata ' , action = ' store_true ' , dest = ' addmetadata ' , default = False ,
2014-01-02 13:47:28 +01:00
help = ' write metadata to the video file ' )
postproc . add_option ( ' --xattrs ' , action = ' store_true ' , dest = ' xattrs ' , default = False ,
help = ' write metadata to the video file \' s xattrs (using dublin core and xdg standards) ' )
2014-01-08 17:53:34 +01:00
postproc . add_option ( ' --prefer-avconv ' , action = ' store_false ' , dest = ' prefer_ffmpeg ' ,
help = ' Prefer avconv over ffmpeg for running the postprocessors (default) ' )
postproc . add_option ( ' --prefer-ffmpeg ' , action = ' store_true ' , dest = ' prefer_ffmpeg ' ,
help = ' Prefer ffmpeg over avconv for running the postprocessors ' )
2012-11-28 02:04:46 +01:00
parser . add_option_group ( general )
parser . add_option_group ( selection )
2013-07-01 14:53:25 +02:00
parser . add_option_group ( downloader )
2012-11-28 02:04:46 +01:00
parser . add_option_group ( filesystem )
parser . add_option_group ( verbosity )
2014-07-24 11:46:21 +02:00
parser . add_option_group ( workarounds )
2012-11-28 02:04:46 +01:00
parser . add_option_group ( video_format )
2013-08-08 09:53:25 +02:00
parser . add_option_group ( subtitles )
2012-11-28 02:04:46 +01:00
parser . add_option_group ( authentication )
parser . add_option_group ( postproc )
2013-04-22 23:05:05 +02:00
if overrideArguments is not None :
opts , args = parser . parse_args ( overrideArguments )
if opts . verbose :
2013-09-16 06:55:33 +02:00
write_string ( u ' [debug] Override config: ' + repr ( overrideArguments ) + ' \n ' )
2012-11-28 02:04:46 +01:00
else :
2013-08-08 09:53:25 +02:00
commandLineConf = sys . argv [ 1 : ]
2014-02-03 06:54:27 +01:00
if ' --ignore-config ' in commandLineConf :
systemConf = [ ]
userConf = [ ]
else :
systemConf = _readOptions ( ' /etc/youtube-dl.conf ' )
if ' --ignore-config ' in systemConf :
userConf = [ ]
else :
userConf = _readUserConf ( )
2013-04-22 23:05:05 +02:00
argv = systemConf + userConf + commandLineConf
2014-02-03 06:54:27 +01:00
2013-04-22 23:05:05 +02:00
opts , args = parser . parse_args ( argv )
2013-04-22 23:15:05 +02:00
if opts . verbose :
2013-09-16 06:55:33 +02:00
write_string ( u ' [debug] System config: ' + repr ( _hide_login_info ( systemConf ) ) + ' \n ' )
write_string ( u ' [debug] User config: ' + repr ( _hide_login_info ( userConf ) ) + ' \n ' )
write_string ( u ' [debug] Command-line args: ' + repr ( _hide_login_info ( commandLineConf ) ) + ' \n ' )
2013-03-12 00:10:05 +01:00
2012-11-28 02:04:46 +01:00
return parser , opts , args
2011-11-21 19:59:59 +01:00
2013-12-16 05:04:12 +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 )
2013-12-16 05:04:12 +01:00
setproctitle ( u ' youtube-dl ' )
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 :
parser . error ( u ' wrong header formatting, it should be key:value, not " %s " ' % h )
key , value = h . split ( ' : ' , 2 )
if opts . verbose :
write_string ( u ' [debug] Adding header from command line option %s : %s \n ' % ( key , value ) )
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-02-25 01:43:17 +01:00
write_string ( u ' [debug] Batch file urls: ' + repr ( batch_urls ) + u ' \n ' )
2012-11-28 02:04:46 +01:00
except IOError :
sys . exit ( u ' 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 :
2013-06-24 15:57:53 +02:00
compat_print ( u ' ' + 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-07-22 04:53:06 +02:00
_SEARCHES = ( u ' cute kittens ' , u ' slithering pythons ' , u ' falling cat ' , u ' angry poodle ' , u ' purple fish ' , u ' running tortoise ' , u ' sleeping bunny ' )
2013-07-01 18:52:19 +02:00
_COUNTS = ( u ' ' , u ' 5 ' , u ' 10 ' , u ' all ' )
desc + = u ' (Example: " %s %s : %s " ) ' % ( ie . SEARCH_KEY , random . choice ( _COUNTS ) , random . choice ( _SEARCHES ) )
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 ) :
parser . error ( u ' using .netrc conflicts with giving username/password ' )
if opts . password is not None and opts . username is None :
2014-01-12 00:27:00 +01:00
parser . error ( u ' 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 ) :
parser . error ( u ' using output template conflicts with using title, video ID or auto number ' )
if opts . usetitle and opts . useid :
parser . error ( u ' using title conflicts with using video ID ' )
if opts . username is not None and opts . password is None :
2014-03-18 14:27:42 +01:00
opts . password = compat_getpass ( u ' 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 :
parser . error ( u ' invalid rate limit specified ' )
opts . ratelimit = numeric_limit
2014-08-03 16:34:04 +02:00
if opts . sleepinterval is not None :
try :
opts . sleepinterval = abs ( int ( opts . sleepinterval ) )
except ValueError :
parser . error ( u ' invalid sleep interval specified ' )
2013-01-22 06:50:42 +01:00
if opts . min_filesize is not None :
numeric_limit = FileDownloader . parse_bytes ( opts . min_filesize )
if numeric_limit is None :
parser . error ( u ' invalid min_filesize specified ' )
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 :
parser . error ( u ' invalid max_filesize specified ' )
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 ) :
2012-11-28 02:04:46 +01:00
parser . error ( u ' invalid retry count specified ' )
if opts . buffersize is not None :
numeric_buffersize = FileDownloader . parse_bytes ( opts . buffersize )
if numeric_buffersize is None :
parser . error ( u ' invalid buffer size specified ' )
opts . buffersize = numeric_buffersize
2013-12-16 13:16:20 +01:00
if opts . playliststart < = 0 :
raise ValueError ( u ' Playlist start must be positive ' )
if opts . playlistend not in ( - 1 , None ) and opts . playlistend < opts . playliststart :
raise ValueError ( u ' 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 ' ] :
2012-11-28 02:04:46 +01:00
parser . error ( u ' invalid audio format specified ' )
if opts . audioquality :
opts . audioquality = opts . audioquality . strip ( ' k ' ) . strip ( ' K ' )
if not opts . audioquality . isdigit ( ) :
parser . error ( u ' 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 ' ] :
2013-01-12 15:07:59 +01:00
parser . error ( u ' 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 )
2014-07-29 17:17:43 +02:00
if opts . default_search not in ( ' auto ' , ' auto_warning ' , ' error ' , ' fixup_error ' , None ) and ' : ' not in opts . default_search :
2014-01-22 14:16:43 +01:00
parser . error ( u ' --default-search invalid; did you forget a colon (:) at the end? ' )
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.
if opts . allsubtitles and ( opts . writeautomaticsub == False ) :
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 ( ) )
2012-12-15 17:44:48 +01:00
outtmpl = ( ( opts . outtmpl is not None and opts . outtmpl )
or ( opts . format == ' -1 ' and opts . usetitle and u ' %(title)s - %(id)s - %(format)s . %(ext)s ' )
or ( opts . format == ' -1 ' and u ' %(id)s - %(format)s . %(ext)s ' )
or ( opts . usetitle and opts . autonumber and u ' %(autonumber)s - %(title)s - %(id)s . %(ext)s ' )
or ( opts . usetitle and u ' %(title)s - %(id)s . %(ext)s ' )
or ( opts . useid and u ' %(id)s . %(ext)s ' )
or ( opts . autonumber and u ' %(autonumber)s - %(id)s . %(ext)s ' )
2014-04-30 10:02:03 +02:00
or DEFAULT_OUTTMPL )
2013-12-15 11:42:38 +01:00
if not os . path . splitext ( outtmpl ) [ 1 ] and opts . extractaudio :
2013-09-21 11:10:22 +02:00
parser . error ( u ' Cannot download a video and extract audio into the same '
2013-12-15 11:42:38 +01:00
u ' file! Use " {0} . %(ext)s " instead of " {0} " as the output '
u ' template ' . format ( outtmpl ) )
2013-09-24 21:55:25 +02:00
2013-12-16 04:15:10 +01: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
2014-01-12 01:27:47 +01:00
download_archive_fn = os . path . expanduser ( opts . download_archive ) if opts . download_archive is not None else opts . download_archive
2013-12-16 04:15:10 +01:00
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 ,
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-06 07:30:07 +02: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 14:59:22 +01:00
' forcejson ' : opts . dumpjson ,
2012-11-28 02:04:46 +01:00
' simulate ' : opts . simulate ,
2013-12-16 04:15:10 +01:00
' skip_download ' : ( opts . skip_download or opts . simulate or any_printing ) ,
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 06:40:07 +02:00
' autonumber_size ' : opts . autonumber_size ,
2012-11-28 02:04:46 +01:00
' restrictfilenames ' : opts . restrictfilenames ,
' ignoreerrors ' : opts . ignoreerrors ,
' ratelimit ' : opts . ratelimit ,
2014-08-03 16:34:04 +02:00
' sleepinterval ' : opts . sleepinterval ,
2012-11-28 02:04:46 +01:00
' 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 ,
2013-09-30 22:26:25 +02: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 07:18:58 +02: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 06:50:42 +01: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 ,
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 :
2013-11-22 19:57:52 +01:00
ydl . print_debug_header ( )
2013-11-17 21:05:14 +01:00
ydl . add_default_info_extractors ( )
# PostProcessors
# Add the metadata pp first, the other pps will copy it
if opts . addmetadata :
ydl . add_post_processor ( FFmpegMetadataPP ( ) )
if opts . extractaudio :
ydl . add_post_processor ( FFmpegExtractAudioPP ( preferredcodec = opts . audioformat , preferredquality = opts . audioquality , nopostoverwrites = opts . nopostoverwrites ) )
if opts . recodevideo :
ydl . add_post_processor ( FFmpegVideoConvertor ( preferedformat = opts . recodevideo ) )
if opts . embedsubtitles :
ydl . add_post_processor ( FFmpegEmbedSubtitlePP ( subtitlesformat = opts . subtitlesformat ) )
2014-01-02 13:47:28 +01:00
if opts . xattrs :
ydl . add_post_processor ( XAttrMetadataPP ( ) )
2014-02-22 13:55:51 +01:00
if opts . embedthumbnail :
2014-02-22 18:31:54 +01:00
if not opts . addmetadata :
ydl . add_post_processor ( FFmpegAudioFixPP ( ) )
2014-02-22 13:55:51 +01:00
ydl . add_post_processor ( AtomicParsleyPP ( ) )
2013-11-17 21:05:14 +01:00
# 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 :
if opts . cachedir is None :
ydl . to_screen ( u ' No cache dir specified (Did you combine --no-cache-dir and --rm-cache-dir?) ' )
else :
if ( ' .cache ' not in opts . cachedir ) or ( ' youtube-dl ' not in opts . cachedir ) :
ydl . to_screen ( u ' Not removing directory %s - this does not look like a cache dir ' )
retcode = 141
else :
ydl . to_screen (
u ' Removing cache dir %s . ' % opts . cachedir ,
skip_eol = True )
if os . path . exists ( opts . cachedir ) :
ydl . to_screen ( u ' . ' , skip_eol = True )
shutil . rmtree ( opts . cachedir )
ydl . to_screen ( u ' . ' )
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-07-24 12:16:16 +02:00
if not ( opts . update_self or opts . rm_cachedir ) :
2013-11-17 21:05:14 +01:00
parser . error ( u ' you must provide at least one URL ' )
else :
sys . exit ( )
2012-11-28 02:04:46 +01:00
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 :
ydl . to_screen ( u ' --max-download limit reached, aborting. ' )
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 :
sys . exit ( u ' ERROR: fixed output name but more than one file to download ' )
except KeyboardInterrupt :
sys . exit ( u ' \n ERROR: Interrupted by user ' )