mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-21 20:46:36 -05:00
Option to present -F output to a more tabular form
This commit is contained in:
parent
2d30509fc8
commit
76d321f68f
5 changed files with 86 additions and 12 deletions
|
@ -420,6 +420,7 @@ ## Video Format Options:
|
||||||
one is requested
|
one is requested
|
||||||
-F, --list-formats List all available formats of requested
|
-F, --list-formats List all available formats of requested
|
||||||
videos
|
videos
|
||||||
|
--list-formats-as-table Present the output of -F in a more tabular form
|
||||||
--youtube-skip-dash-manifest Do not download the DASH manifests and
|
--youtube-skip-dash-manifest Do not download the DASH manifests and
|
||||||
related data on YouTube videos
|
related data on YouTube videos
|
||||||
--youtube-skip-hls-manifest Do not download the HLS manifests and
|
--youtube-skip-hls-manifest Do not download the HLS manifests and
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
expand_path,
|
expand_path,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
format_bytes,
|
format_bytes,
|
||||||
|
format_field,
|
||||||
formatSeconds,
|
formatSeconds,
|
||||||
GeoRestrictedError,
|
GeoRestrictedError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
|
@ -2382,19 +2383,62 @@ def _format_note(self, fdict):
|
||||||
res += '~' + format_bytes(fdict['filesize_approx'])
|
res += '~' + format_bytes(fdict['filesize_approx'])
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _format_note_table(self, f):
|
||||||
|
def join_fields(*vargs):
|
||||||
|
return ', '.join((val for val in vargs if val != ''))
|
||||||
|
|
||||||
|
return join_fields(
|
||||||
|
'UNSUPPORTED' if f.get('ext') in ('f4f', 'f4m') else '',
|
||||||
|
format_field(f, 'language', '[%s]'),
|
||||||
|
format_field(f, 'format_note'),
|
||||||
|
format_field(f, 'container', ignore=(None, f.get('ext'))),
|
||||||
|
format_field(f, 'asr', '%5dHz'))
|
||||||
|
|
||||||
def list_formats(self, info_dict):
|
def list_formats(self, info_dict):
|
||||||
formats = info_dict.get('formats', [info_dict])
|
formats = info_dict.get('formats', [info_dict])
|
||||||
table = [
|
new_format = self.params.get('listformats_table', False)
|
||||||
[f['format_id'], f['ext'], self.format_resolution(f), self._format_note(f)]
|
if new_format:
|
||||||
for f in formats
|
table = [
|
||||||
if f.get('preference') is None or f['preference'] >= -1000]
|
[
|
||||||
# if len(formats) > 1:
|
format_field(f, 'format_id'),
|
||||||
# table[-1][-1] += (' ' if table[-1][-1] else '') + '(best*)'
|
format_field(f, 'ext'),
|
||||||
|
self.format_resolution(f),
|
||||||
|
format_field(f, 'fps', '%d'),
|
||||||
|
'|',
|
||||||
|
format_field(f, 'filesize', ' %s', func=format_bytes) + format_field(f, 'filesize_approx', '~%s', func=format_bytes),
|
||||||
|
format_field(f, 'tbr', '%4dk'),
|
||||||
|
f.get('protocol').replace('http_dash_segments', 'dash').replace("native", "n"),
|
||||||
|
'|',
|
||||||
|
format_field(f, 'vcodec', default='unknown').replace('none', ''),
|
||||||
|
format_field(f, 'vbr', '%4dk'),
|
||||||
|
format_field(f, 'acodec', default='unknown').replace('none', ''),
|
||||||
|
format_field(f, 'abr', '%3dk'),
|
||||||
|
format_field(f, 'asr', '%5dHz'),
|
||||||
|
self._format_note_table(f)]
|
||||||
|
for f in formats
|
||||||
|
if f.get('preference') is None or f['preference'] >= -1000]
|
||||||
|
header_line = ['ID', 'EXT', 'RESOLUTION', 'FPS', '|', ' FILESIZE', ' TBR', 'PROTO',
|
||||||
|
'|', 'VCODEC', ' VBR', 'ACODEC', ' ABR', ' ASR', 'NOTE']
|
||||||
|
else:
|
||||||
|
table = [
|
||||||
|
[
|
||||||
|
format_field(f, 'format_id'),
|
||||||
|
format_field(f, 'ext'),
|
||||||
|
self.format_resolution(f),
|
||||||
|
self._format_note(f)]
|
||||||
|
for f in formats
|
||||||
|
if f.get('preference') is None or f['preference'] >= -1000]
|
||||||
|
header_line = ['format code', 'extension', 'resolution', 'note']
|
||||||
|
|
||||||
header_line = ['format code', 'extension', 'resolution', 'note']
|
# if len(formats) > 1:
|
||||||
|
# table[-1][-1] += (' ' if table[-1][-1] else '') + '(best)'
|
||||||
self.to_screen(
|
self.to_screen(
|
||||||
'[info] Available formats for %s:\n%s' %
|
'[info] Available formats for %s:\n%s' % (info_dict['id'], render_table(
|
||||||
(info_dict['id'], render_table(header_line, table)))
|
header_line,
|
||||||
|
table,
|
||||||
|
delim=new_format,
|
||||||
|
extraGap=(0 if new_format else 1),
|
||||||
|
hideEmpty=new_format)))
|
||||||
|
|
||||||
def list_thumbnails(self, info_dict):
|
def list_thumbnails(self, info_dict):
|
||||||
thumbnails = info_dict.get('thumbnails')
|
thumbnails = info_dict.get('thumbnails')
|
||||||
|
|
|
@ -358,6 +358,7 @@ def parse_retries(retries):
|
||||||
'allow_multiple_video_streams': opts.allow_multiple_video_streams,
|
'allow_multiple_video_streams': opts.allow_multiple_video_streams,
|
||||||
'allow_multiple_audio_streams': opts.allow_multiple_audio_streams,
|
'allow_multiple_audio_streams': opts.allow_multiple_audio_streams,
|
||||||
'listformats': opts.listformats,
|
'listformats': opts.listformats,
|
||||||
|
'listformats_table': opts.listformats_table,
|
||||||
'outtmpl': outtmpl,
|
'outtmpl': outtmpl,
|
||||||
'autonumber_size': opts.autonumber_size,
|
'autonumber_size': opts.autonumber_size,
|
||||||
'autonumber_start': opts.autonumber_start,
|
'autonumber_start': opts.autonumber_start,
|
||||||
|
|
|
@ -443,6 +443,14 @@ def _comma_separated_values_options_callback(option, opt_str, value, parser):
|
||||||
'-F', '--list-formats',
|
'-F', '--list-formats',
|
||||||
action='store_true', dest='listformats',
|
action='store_true', dest='listformats',
|
||||||
help='List all available formats of requested videos')
|
help='List all available formats of requested videos')
|
||||||
|
video_format.add_option(
|
||||||
|
'--list-formats-as-table',
|
||||||
|
action='store_true', dest='listformats_table', default=False,
|
||||||
|
help='Present the output of -F in a more tabular form')
|
||||||
|
video_format.add_option(
|
||||||
|
'--list-formats-old',
|
||||||
|
action='store_false', dest='listformats_table',
|
||||||
|
help=optparse.SUPPRESS_HELP)
|
||||||
video_format.add_option(
|
video_format.add_option(
|
||||||
'--youtube-include-dash-manifest',
|
'--youtube-include-dash-manifest',
|
||||||
action='store_true', dest='youtube_include_dash_manifest', default=True,
|
action='store_true', dest='youtube_include_dash_manifest', default=True,
|
||||||
|
|
|
@ -4315,11 +4315,25 @@ def determine_protocol(info_dict):
|
||||||
return compat_urllib_parse_urlparse(url).scheme
|
return compat_urllib_parse_urlparse(url).scheme
|
||||||
|
|
||||||
|
|
||||||
def render_table(header_row, data):
|
def render_table(header_row, data, delim=False, extraGap=0, hideEmpty=False):
|
||||||
""" Render a list of rows, each as a list of values """
|
""" Render a list of rows, each as a list of values """
|
||||||
|
|
||||||
|
def get_max_lens(table):
|
||||||
|
return [max(len(compat_str(v)) for v in col) for col in zip(*table)]
|
||||||
|
|
||||||
|
def filter_using_list(row, filterArray):
|
||||||
|
return [col for (take, col) in zip(filterArray, row) if take]
|
||||||
|
|
||||||
|
if hideEmpty:
|
||||||
|
max_lens = get_max_lens(data)
|
||||||
|
header_row = filter_using_list(header_row, max_lens)
|
||||||
|
data = [filter_using_list(row, max_lens) for row in data]
|
||||||
|
|
||||||
table = [header_row] + data
|
table = [header_row] + data
|
||||||
max_lens = [max(len(compat_str(v)) for v in col) for col in zip(*table)]
|
max_lens = get_max_lens(table)
|
||||||
format_str = ' '.join('%-' + compat_str(ml + 1) + 's' for ml in max_lens[:-1]) + '%s'
|
if delim:
|
||||||
|
table = [header_row] + [['-' * ml for ml in max_lens]] + data
|
||||||
|
format_str = ' '.join('%-' + compat_str(ml + extraGap) + 's' for ml in max_lens[:-1]) + ' %s'
|
||||||
return '\n'.join(format_str % tuple(row) for row in table)
|
return '\n'.join(format_str % tuple(row) for row in table)
|
||||||
|
|
||||||
|
|
||||||
|
@ -5795,3 +5809,9 @@ def to_high_limit_path(path):
|
||||||
return r'\\?\ '.rstrip() + os.path.abspath(path)
|
return r'\\?\ '.rstrip() + os.path.abspath(path)
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def format_field(obj, field, template='%s', ignore=(None, ''), default='', func=None):
|
||||||
|
val = obj.get(field, default)
|
||||||
|
if func and val not in ignore:
|
||||||
|
val = func(val)
|
||||||
|
return template % val if val not in ignore else default
|
||||||
|
|
Loading…
Reference in a new issue