@ -216,10 +216,10 @@ class YoutubeDL(object):
If stderr is a tty file the ' WARNING: ' will be colored
If stderr is a tty file the ' WARNING: ' will be colored
'''
'''
if sys . stderr . isatty ( ) and os . name != ' nt ' :
if sys . stderr . isatty ( ) and os . name != ' nt ' :
_msg_header = u ' \033 [0;33mWARNING: \033 [0m '
_msg_header = u ' \033 [0;33mWARNING: \033 [0m '
else :
else :
_msg_header = u ' WARNING: '
_msg_header = u ' WARNING: '
warning_message = u ' %s %s ' % ( _msg_header , message )
warning_message = u ' %s %s ' % ( _msg_header , message )
self . to_stderr ( warning_message )
self . to_stderr ( warning_message )
def report_error ( self , message , tb = None ) :
def report_error ( self , message , tb = None ) :
@ -234,19 +234,6 @@ class YoutubeDL(object):
error_message = u ' %s %s ' % ( _msg_header , message )
error_message = u ' %s %s ' % ( _msg_header , message )
self . trouble ( error_message , tb )
self . trouble ( error_message , tb )
def slow_down ( self , start_time , byte_counter ) :
""" Sleep if the download speed is over the rate limit. """
rate_limit = self . params . get ( ' ratelimit ' , None )
if rate_limit is None or byte_counter == 0 :
return
now = time . time ( )
elapsed = now - start_time
if elapsed < = 0.0 :
return
speed = float ( byte_counter ) / elapsed
if speed > rate_limit :
time . sleep ( ( byte_counter - rate_limit * ( now - start_time ) ) / rate_limit )
def report_writedescription ( self , descfn ) :
def report_writedescription ( self , descfn ) :
""" Report that the description file is being written """
""" Report that the description file is being written """
self . to_screen ( u ' [info] Writing video description to: ' + descfn )
self . to_screen ( u ' [info] Writing video description to: ' + descfn )
@ -421,8 +408,8 @@ class YoutubeDL(object):
self . to_screen ( u " [ %s ] playlist ' %s ' : Collected %d video ids (downloading %d of them) " %
self . to_screen ( u " [ %s ] playlist ' %s ' : Collected %d video ids (downloading %d of them) " %
( ie_result [ ' extractor ' ] , playlist , n_all_entries , n_entries ) )
( ie_result [ ' extractor ' ] , playlist , n_all_entries , n_entries ) )
for i , entry in enumerate ( entries , 1 ) :
for i , entry in enumerate ( entries , 1 ) :
self . to_screen ( u ' [download] Downloading video # %s of %s ' % ( i , n_entries ) )
self . to_screen ( u ' [download] Downloading video # %s of %s ' % ( i , n_entries ) )
extra = {
extra = {
' playlist ' : playlist ,
' playlist ' : playlist ,
' playlist_index ' : i + playliststart ,
' playlist_index ' : i + playliststart ,
@ -450,6 +437,22 @@ class YoutubeDL(object):
else :
else :
raise Exception ( ' Invalid result type: %s ' % result_type )
raise Exception ( ' Invalid result type: %s ' % result_type )
def select_format ( self , format_spec , available_formats ) :
if format_spec == ' best ' or format_spec is None :
return available_formats [ - 1 ]
elif format_spec == ' worst ' :
return available_formats [ 0 ]
else :
extensions = [ u ' mp4 ' , u ' flv ' , u ' webm ' , u ' 3gp ' ]
if format_spec in extensions :
filter_f = lambda f : f [ ' ext ' ] == format_spec
else :
filter_f = lambda f : f [ ' format_id ' ] == format_spec
matches = list ( filter ( filter_f , available_formats ) )
if matches :
return matches [ - 1 ]
return None
def process_video_result ( self , info_dict , download = True ) :
def process_video_result ( self , info_dict , download = True ) :
assert info_dict . get ( ' _type ' , ' video ' ) == ' video '
assert info_dict . get ( ' _type ' , ' video ' ) == ' video '
@ -460,6 +463,7 @@ class YoutubeDL(object):
# This extractors handle format selection themselves
# This extractors handle format selection themselves
if info_dict [ ' extractor ' ] in [ u ' youtube ' , u ' Youku ' , u ' YouPorn ' , u ' mixcloud ' ] :
if info_dict [ ' extractor ' ] in [ u ' youtube ' , u ' Youku ' , u ' YouPorn ' , u ' mixcloud ' ] :
if download :
self . process_info ( info_dict )
self . process_info ( info_dict )
return info_dict
return info_dict
@ -472,17 +476,14 @@ class YoutubeDL(object):
# We check that all the formats have the format and format_id fields
# We check that all the formats have the format and format_id fields
for ( i , format ) in enumerate ( formats ) :
for ( i , format ) in enumerate ( formats ) :
if format . get ( ' format ' ) is None :
if format . get ( ' height ' ) is not None :
if format . get ( ' width ' ) is not None :
format_desc = u ' %s x %s ' % ( format [ ' width ' ] , format [ ' height ' ] )
else :
format_desc = u ' %s p ' % format [ ' height ' ]
else :
format_desc = ' ??? '
format [ ' format ' ] = format_desc
if format . get ( ' format_id ' ) is None :
if format . get ( ' format_id ' ) is None :
format [ ' format_id ' ] = compat_str ( i )
format [ ' format_id ' ] = compat_str ( i )
if format . get ( ' format ' ) is None :
format [ ' format ' ] = u ' {id} - {res} {note} ' . format (
id = format [ ' format_id ' ] ,
res = self . format_resolution ( format ) ,
note = u ' ( {} ) ' . format ( format [ ' format_note ' ] ) if format . get ( ' format_note ' ) is not None else ' ' ,
)
if self . params . get ( ' listformats ' , None ) :
if self . params . get ( ' listformats ' , None ) :
self . list_formats ( info_dict )
self . list_formats ( info_dict )
@ -504,22 +505,20 @@ class YoutubeDL(object):
formats = sorted ( formats , key = _free_formats_key )
formats = sorted ( formats , key = _free_formats_key )
req_format = self . params . get ( ' format ' , ' best ' )
req_format = self . params . get ( ' format ' , ' best ' )
if req_format is None :
req_format = ' best '
formats_to_download = [ ]
formats_to_download = [ ]
if req_format == ' best ' or req_format is None :
formats_to_download = [ formats [ - 1 ] ]
elif req_format == ' worst ' :
formats_to_download = [ formats [ 0 ] ]
# The -1 is for supporting YoutubeIE
# The -1 is for supporting YoutubeIE
el if req_format in ( ' -1 ' , ' all ' ) :
if req_format in ( ' -1 ' , ' all ' ) :
formats_to_download = formats
formats_to_download = formats
else :
else :
# We can accept formats requestd in the format: 34/ 10/ 5, we pick
# We can accept formats requestd in the format: 34/ 5/best , we pick
# the first that is available, starting from left
# the first that is available, starting from left
req_formats = req_format . split ( ' / ' )
req_formats = req_format . split ( ' / ' )
for rf in req_formats :
for rf in req_formats :
matches = filter ( lambda f : f [ ' format_id ' ] == rf , formats )
selected_format = self . select_format ( rf , formats )
if matches :
if selected_format is not None :
formats_to_download = [ matches[ 0 ] ]
formats_to_download = [ selected_for mat]
break
break
if not formats_to_download :
if not formats_to_download :
raise ExtractorError ( u ' requested format not available ' )
raise ExtractorError ( u ' requested format not available ' )
@ -645,7 +644,7 @@ class YoutubeDL(object):
infofn = filename + u ' .info.json '
infofn = filename + u ' .info.json '
self . report_writeinfojson ( infofn )
self . report_writeinfojson ( infofn )
try :
try :
json_info_dict = dict ( ( k , v ) for k , v in info_dict . items ( ) if not k in [ ' urlhandle ' ] )
json_info_dict = dict ( ( k , v ) for k , v in info_dict . items ( ) if not k in [ ' urlhandle ' ] )
write_json_file ( json_info_dict , encodeFilename ( infofn ) )
write_json_file ( json_info_dict , encodeFilename ( infofn ) )
except ( OSError , IOError ) :
except ( OSError , IOError ) :
self . report_error ( u ' Cannot write metadata to JSON file ' + infofn )
self . report_error ( u ' Cannot write metadata to JSON file ' + infofn )
@ -715,7 +714,7 @@ class YoutubeDL(object):
keep_video = None
keep_video = None
for pp in self . _pps :
for pp in self . _pps :
try :
try :
keep_video_wish , new_info = pp . run ( info )
keep_video_wish , new_info = pp . run ( info )
if keep_video_wish is not None :
if keep_video_wish is not None :
if keep_video_wish :
if keep_video_wish :
keep_video = keep_video_wish
keep_video = keep_video_wish
@ -754,16 +753,31 @@ class YoutubeDL(object):
with locked_file ( fn , ' a ' , encoding = ' utf-8 ' ) as archive_file :
with locked_file ( fn , ' a ' , encoding = ' utf-8 ' ) as archive_file :
archive_file . write ( vid_id + u ' \n ' )
archive_file . write ( vid_id + u ' \n ' )
@staticmethod
def format_resolution ( format ) :
if format . get ( ' height ' ) is not None :
if format . get ( ' width ' ) is not None :
res = u ' %s x %s ' % ( format [ ' width ' ] , format [ ' height ' ] )
else :
res = u ' %s p ' % format [ ' height ' ]
else :
res = ' ??? '
return res
def list_formats ( self , info_dict ) :
def list_formats ( self , info_dict ) :
formats_s = [ ]
formats_s = [ ]
for format in info_dict . get ( ' formats ' , [ info_dict ] ) :
for format in info_dict . get ( ' formats ' , [ info_dict ] ) :
formats_s . append ( " %s \t : \t %s \t [ %s ] " % ( format [ ' format_id ' ] ,
formats_s . append ( u ' %-15s : %-5s %-15s [ %s ] ' % (
format [ ' format_id ' ] ,
format [ ' ext ' ] ,
format [ ' ext ' ] ,
format . get ( ' format ' , ' ??? ' ) ,
format . get ( ' format_note ' ) or ' - ' ,
self . format_resolution ( format ) ,
)
)
)
)
if len ( formats_s ) != 1 :
if len ( formats_s ) != 1 :
formats_s [ 0 ] + = ' (worst) '
formats_s [ 0 ] + = ' (worst) '
formats_s [ - 1 ] + = ' (best) '
formats_s [ - 1 ] + = ' (best) '
formats_s = " \n " . join ( formats_s )
formats_s = " \n " . join ( formats_s )
self . to_screen ( u " [info] Available formats for %s : \n format code \t extension \n %s " % ( info_dict [ ' id ' ] , formats_s ) )
self . to_screen ( u ' [info] Available formats for %s : \n '
u ' format code extension note resolution \n %s ' % (
info_dict [ ' id ' ] , formats_s ) )