# Author: Vasyl' Vavrychuk
# License: Public domain code
import cookielib
+import ctypes
import datetime
import htmlentitydefs
import httplib
'User-Agent': 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101028 Firefox/3.6.12',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+ 'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-us,en;q=0.5',
}
playliststart: Playlist item to start at.
playlistend: Playlist item to end at.
logtostderr: Log messages to stderr instead of stdout.
+ consoletitle: Display progress in console window's titlebar.
"""
params = None
"""Print message to stderr."""
print >>sys.stderr, message.encode(preferredencoding())
+ def to_cons_title(self, message):
+ """Set console/terminal window title to message."""
+ if not self.params.get('consoletitle', False):
+ return
+ if os.name == 'nt' and ctypes.windll.kernel32.GetConsoleWindow():
+ # c_wchar_p() might not be necessary if `message` is
+ # already of type unicode()
+ ctypes.windll.kernel32.SetConsoleTitleW(ctypes.c_wchar_p(message))
+ elif 'TERM' in os.environ:
+ sys.stderr.write('\033]0;%s\007' % message.encode(preferredencoding()))
+
def fixed_template(self):
"""Checks if the output template is fixed."""
return (re.search(ur'(?u)%\(.+?\)s', self.params['outtmpl']) is None)
return
self.to_screen(u'\r[download] %s of %s at %s ETA %s' %
(percent_str, data_len_str, speed_str, eta_str), skip_eol=True)
+ self.to_cons_title(u'youtube-dl - %s of %s at %s ETA %s' %
+ (percent_str.strip(), data_len_str.strip(), speed_str.strip(), eta_str.strip()))
def report_resuming_byte(self, resume_len):
"""Report attempt to resume at given byte."""
return False
data_len = data.info().get('Content-length', None)
+ if data_len is not None:
+ data_len = long(data_len) + resume_len
data_len_str = self.format_bytes(data_len)
- byte_counter = 0
+ byte_counter = 0 + resume_len
block_size = 1024
start = time.time()
while True:
before = time.time()
data_block = data.read(block_size)
after = time.time()
- data_block_len = len(data_block)
- if data_block_len == 0:
+ if len(data_block) == 0:
break
- byte_counter += data_block_len
+ byte_counter += len(data_block)
# Open file just in time
if stream is None:
except (IOError, OSError), err:
self.trouble(u'\nERROR: unable to write data: %s' % str(err))
return False
- block_size = self.best_block_size(after - before, data_block_len)
+ block_size = self.best_block_size(after - before, len(data_block))
# Progress message
percent_str = self.calc_percent(byte_counter, data_len)
- eta_str = self.calc_eta(start, time.time(), data_len, byte_counter)
- speed_str = self.calc_speed(start, time.time(), byte_counter)
+ eta_str = self.calc_eta(start, time.time(), data_len - resume_len, byte_counter - resume_len)
+ speed_str = self.calc_speed(start, time.time(), byte_counter - resume_len)
self.report_progress(percent_str, data_len_str, speed_str, eta_str)
# Apply rate limit
- self.slow_down(start, byte_counter)
+ self.slow_down(start, byte_counter - resume_len)
stream.close()
self.report_finish()
- if data_len is not None and str(byte_counter) != data_len:
+ if data_len is not None and byte_counter != data_len:
raise ContentTooShortError(byte_counter, long(data_len))
self.try_rename(tmpfilename, filename)
return True
video_token = urllib.unquote_plus(video_info['token'][0])
# Decide which formats to download
- requested_format = self._downloader.params.get('format', None)
- get_video_template = 'http://www.youtube.com/get_video?video_id=%s&t=%s&eurl=&el=&ps=&asv=&fmt=%%s' % (video_id, video_token)
+ req_format = self._downloader.params.get('format', None)
if 'fmt_url_map' in video_info:
url_map = dict(tuple(pair.split('|')) for pair in video_info['fmt_url_map'][0].split(','))
if len(existing_formats) == 0:
self._downloader.trouble(u'ERROR: no known formats available for video')
return
- if requested_format is None:
+ if req_format is None:
video_url_list = [(existing_formats[0], url_map[existing_formats[0]])] # Best quality
- elif requested_format == '-1':
+ elif req_format == '-1':
video_url_list = [(f, url_map[f]) for f in existing_formats] # All formats
else:
- video_url_list = [(requested_format, get_video_template % requested_format)] # Specific format
+ # Specific format
+ if req_format not in url_map:
+ self._downloader.trouble(u'ERROR: requested format not available')
+ return
+ video_url_list = [(req_format, url_map[req_format])] # Specific format
elif 'conn' in video_info and video_info['conn'][0].startswith('rtmp'):
self.report_rtmp_download()
'player_url': player_url,
})
except UnavailableVideoError, err:
- self._downloader.trouble(u'ERROR: unable to download video (format may not be available)')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class MetacafeIE(InfoExtractor):
'player_url': None,
})
except UnavailableVideoError:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class DailymotionIE(InfoExtractor):
'player_url': None,
})
except UnavailableVideoError:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class GoogleIE(InfoExtractor):
"""Information extractor for video.google.com."""
'player_url': None,
})
except UnavailableVideoError:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class PhotobucketIE(InfoExtractor):
'player_url': None,
})
except UnavailableVideoError:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class YahooIE(InfoExtractor):
'player_url': None,
})
except UnavailableVideoError:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class GenericIE(InfoExtractor):
'player_url': None,
})
except UnavailableVideoError, err:
- self._downloader.trouble(u'ERROR: unable to download video')
+ self._downloader.trouble(u'\nERROR: unable to download video')
class YoutubeSearchIE(InfoExtractor):
dest='playliststart', metavar='NUMBER', help='playlist video to start at (default is 1)', default=1)
parser.add_option('--playlist-end',
dest='playlistend', metavar='NUMBER', help='playlist video to end at (default is last)', default=-1)
+ parser.add_option('--dump-user-agent',
+ action='store_true', dest='dump_user_agent', help='display the current browser identification', default=False)
authentication = optparse.OptionGroup(parser, 'Authentication Options')
authentication.add_option('-u', '--username',
video_format = optparse.OptionGroup(parser, 'Video Format Options')
video_format.add_option('-f', '--format',
action='store', dest='format', metavar='FORMAT', help='video format code')
- video_format.add_option('-m', '--mobile-version',
- action='store_const', dest='format', help='alias for -f 17', const='17')
video_format.add_option('--all-formats',
action='store_const', dest='format', help='download all available video formats', const='-1')
video_format.add_option('--max-quality',
action='store', dest='format_limit', metavar='FORMAT', help='highest quality format to download')
- video_format.add_option('-b', '--best-quality',
- action='store_true', dest='bestquality', help='download the best video quality (DEPRECATED)')
parser.add_option_group(video_format)
verbosity = optparse.OptionGroup(parser, 'Verbosity / Simulation Options')
action='store_true', dest='getdescription', help='simulate, quiet but print video description', default=False)
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)
parser.add_option_group(verbosity)
filesystem = optparse.OptionGroup(parser, 'Filesystem Options')
except (IOError, OSError), err:
sys.exit(u'ERROR: unable to open cookie file')
+ # Dump user agent
+ if opts.dump_user_agent:
+ print std_headers['User-Agent']
+ sys.exit(0)
+
# General configuration
cookie_processor = urllib2.HTTPCookieProcessor(jar)
urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()))
all_urls = batchurls + args
# Conflicting, missing and erroneous options
- if opts.bestquality:
- print >>sys.stderr, u'\nWARNING: -b/--best-quality IS DEPRECATED AS IT IS THE DEFAULT BEHAVIOR NOW\n'
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:
'playliststart': opts.playliststart,
'playlistend': opts.playlistend,
'logtostderr': opts.outtmpl == '-',
+ 'consoletitle': opts.consoletitle,
})
fd.add_info_extractor(youtube_search_ie)
fd.add_info_extractor(youtube_pl_ie)