mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	@@ -1495,7 +1495,7 @@ class YoutubeDL(object):
 | 
			
		||||
                self.write_debug('Additional URLs: "%s"' % '", "'.join(additional_urls))
 | 
			
		||||
                ie_result['additional_entries'] = [
 | 
			
		||||
                    self.extract_info(
 | 
			
		||||
                        url, download, extra_info,
 | 
			
		||||
                        url, download, extra_info=extra_info,
 | 
			
		||||
                        force_generic_extractor=self.params.get('force_generic_extractor'))
 | 
			
		||||
                    for url in additional_urls
 | 
			
		||||
                ]
 | 
			
		||||
@@ -2474,10 +2474,7 @@ class YoutubeDL(object):
 | 
			
		||||
                    info_dict['id'], automatic_captions, 'automatic captions')
 | 
			
		||||
            self.list_subtitles(info_dict['id'], subtitles, 'subtitles')
 | 
			
		||||
        if self.params.get('listformats') or interactive_format_selection:
 | 
			
		||||
            if not info_dict.get('formats') and not info_dict.get('url'):
 | 
			
		||||
                self.to_screen('%s has no formats' % info_dict['id'])
 | 
			
		||||
            else:
 | 
			
		||||
                self.list_formats(info_dict)
 | 
			
		||||
            self.list_formats(info_dict)
 | 
			
		||||
        if list_only:
 | 
			
		||||
            # Without this printing, -F --print-json will not work
 | 
			
		||||
            self.__forced_printings(info_dict, self.prepare_filename(info_dict), incomplete=True)
 | 
			
		||||
@@ -3361,6 +3358,11 @@ class YoutubeDL(object):
 | 
			
		||||
        return headers
 | 
			
		||||
 | 
			
		||||
    def list_formats(self, info_dict):
 | 
			
		||||
        if not info_dict.get('formats') and not info_dict.get('url'):
 | 
			
		||||
            self.to_screen('%s has no formats' % info_dict['id'])
 | 
			
		||||
            return
 | 
			
		||||
        self.to_screen('[info] Available formats for %s:' % info_dict['id'])
 | 
			
		||||
 | 
			
		||||
        formats = info_dict.get('formats', [info_dict])
 | 
			
		||||
        new_format = self.params.get('listformats_table', True) is not False
 | 
			
		||||
        if new_format:
 | 
			
		||||
@@ -3375,7 +3377,7 @@ class YoutubeDL(object):
 | 
			
		||||
                    delim,
 | 
			
		||||
                    format_field(f, 'filesize', ' \t%s', func=format_bytes) + format_field(f, 'filesize_approx', '~\t%s', func=format_bytes),
 | 
			
		||||
                    format_field(f, 'tbr', '\t%dk'),
 | 
			
		||||
                    shorten_protocol_name(f.get('protocol', '').replace('native', 'n')),
 | 
			
		||||
                    shorten_protocol_name(f.get('protocol', '')),
 | 
			
		||||
                    delim,
 | 
			
		||||
                    format_field(f, 'vcodec', default='unknown').replace(
 | 
			
		||||
                        'none',
 | 
			
		||||
@@ -3411,8 +3413,6 @@ class YoutubeDL(object):
 | 
			
		||||
                if f.get('preference') is None or f['preference'] >= -1000]
 | 
			
		||||
            header_line = ['format code', 'extension', 'resolution', 'note']
 | 
			
		||||
 | 
			
		||||
        self.to_screen(
 | 
			
		||||
            '[info] Available formats for %s:' % info_dict['id'])
 | 
			
		||||
        self.to_stdout(render_table(
 | 
			
		||||
            header_line, table,
 | 
			
		||||
            extra_gap=(0 if new_format else 1),
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ from .options import (
 | 
			
		||||
)
 | 
			
		||||
from .compat import (
 | 
			
		||||
    compat_getpass,
 | 
			
		||||
    compat_os_name,
 | 
			
		||||
    compat_shlex_quote,
 | 
			
		||||
    workaround_optparse_bug9161,
 | 
			
		||||
)
 | 
			
		||||
@@ -95,7 +96,8 @@ def _real_main(argv=None):
 | 
			
		||||
    if opts.batchfile is not None:
 | 
			
		||||
        try:
 | 
			
		||||
            if opts.batchfile == '-':
 | 
			
		||||
                write_string('Reading URLs from stdin:\n')
 | 
			
		||||
                write_string('Reading URLs from stdin - EOF (%s) to end:\n' % (
 | 
			
		||||
                    'Ctrl+Z' if compat_os_name == 'nt' else 'Ctrl+D'))
 | 
			
		||||
                batchfd = sys.stdin
 | 
			
		||||
            else:
 | 
			
		||||
                batchfd = io.open(
 | 
			
		||||
@@ -518,7 +520,7 @@ def _real_main(argv=None):
 | 
			
		||||
            if len(dur) == 2 and all(t is not None for t in dur):
 | 
			
		||||
                remove_ranges.append(tuple(dur))
 | 
			
		||||
                continue
 | 
			
		||||
            parser.error(f'invalid --remove-chapters time range {regex!r}. Must be of the form ?start-end')
 | 
			
		||||
            parser.error(f'invalid --remove-chapters time range {regex!r}. Must be of the form *start-end')
 | 
			
		||||
        try:
 | 
			
		||||
            remove_chapters_patterns.append(re.compile(regex))
 | 
			
		||||
        except re.error as err:
 | 
			
		||||
 
 | 
			
		||||
@@ -397,6 +397,7 @@ class FileDownloader(object):
 | 
			
		||||
                    'status': 'finished',
 | 
			
		||||
                    'total_bytes': os.path.getsize(encodeFilename(filename)),
 | 
			
		||||
                }, info_dict)
 | 
			
		||||
                self._finish_multiline_status()
 | 
			
		||||
                return True, False
 | 
			
		||||
 | 
			
		||||
        if subtitle is False:
 | 
			
		||||
 
 | 
			
		||||
@@ -340,7 +340,7 @@ class CBCGemIE(InfoExtractor):
 | 
			
		||||
                yield {
 | 
			
		||||
                    **base_format,
 | 
			
		||||
                    'format_id': join_nonempty('sec', height),
 | 
			
		||||
                    'url': re.sub(r'(QualityLevels\()\d+(\))', fr'\<1>{bitrate}\2', base_url),
 | 
			
		||||
                    'url': re.sub(r'(QualityLevels\()\d+(\))', fr'\1{bitrate}\2', base_url),
 | 
			
		||||
                    'width': int_or_none(video_quality.attrib.get('MaxWidth')),
 | 
			
		||||
                    'tbr': bitrate / 1000.0,
 | 
			
		||||
                    'height': height,
 | 
			
		||||
 
 | 
			
		||||
@@ -616,7 +616,7 @@ class InfoExtractor(object):
 | 
			
		||||
            kwargs = {
 | 
			
		||||
                'video_id': e.video_id or self.get_temp_id(url),
 | 
			
		||||
                'ie': self.IE_NAME,
 | 
			
		||||
                'tb': e.traceback,
 | 
			
		||||
                'tb': e.traceback or sys.exc_info()[2],
 | 
			
		||||
                'expected': e.expected,
 | 
			
		||||
                'cause': e.cause
 | 
			
		||||
            }
 | 
			
		||||
@@ -1574,7 +1574,7 @@ class InfoExtractor(object):
 | 
			
		||||
            'vcodec': {'type': 'ordered', 'regex': True,
 | 
			
		||||
                       'order': ['av0?1', 'vp0?9.2', 'vp0?9', '[hx]265|he?vc?', '[hx]264|avc', 'vp0?8', 'mp4v|h263', 'theora', '', None, 'none']},
 | 
			
		||||
            'acodec': {'type': 'ordered', 'regex': True,
 | 
			
		||||
                       'order': ['opus', 'vorbis', 'aac', 'mp?4a?', 'mp3', 'e-?a?c-?3', 'ac-?3', 'dts', '', None, 'none']},
 | 
			
		||||
                       'order': ['[af]lac', 'wav|aiff', 'opus', 'vorbis', 'aac', 'mp?4a?', 'mp3', 'e-?a?c-?3', 'ac-?3', 'dts', '', None, 'none']},
 | 
			
		||||
            'hdr': {'type': 'ordered', 'regex': True, 'field': 'dynamic_range',
 | 
			
		||||
                    'order': ['dv', '(hdr)?12', r'(hdr)?10\+', '(hdr)?10', 'hlg', '', 'sdr', None]},
 | 
			
		||||
            'proto': {'type': 'ordered', 'regex': True, 'field': 'protocol',
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ class FancodeVodIE(InfoExtractor):
 | 
			
		||||
    _ACCESS_TOKEN = None
 | 
			
		||||
    _NETRC_MACHINE = 'fancode'
 | 
			
		||||
 | 
			
		||||
    _LOGIN_HINT = 'Use "--user refresh --password <refresh_token>" to login using a refresh token'
 | 
			
		||||
    _LOGIN_HINT = 'Use "--username refresh --password <refresh_token>" to login using a refresh token'
 | 
			
		||||
 | 
			
		||||
    headers = {
 | 
			
		||||
        'content-type': 'application/json',
 | 
			
		||||
 
 | 
			
		||||
@@ -258,8 +258,7 @@ class PornHubIE(PornHubBaseIE):
 | 
			
		||||
            webpage)
 | 
			
		||||
 | 
			
		||||
    def _extract_count(self, pattern, webpage, name):
 | 
			
		||||
        return str_to_int(self._search_regex(
 | 
			
		||||
            pattern, webpage, '%s count' % name, fatal=False))
 | 
			
		||||
        return str_to_int(self._search_regex(pattern, webpage, '%s count' % name, default=None))
 | 
			
		||||
 | 
			
		||||
    def _real_extract(self, url):
 | 
			
		||||
        mobj = self._match_valid_url(url)
 | 
			
		||||
 
 | 
			
		||||
@@ -99,7 +99,7 @@ class RoosterTeethIE(RoosterTeethBaseIE):
 | 
			
		||||
            'series': 'Million Dollars, But...',
 | 
			
		||||
            'episode': 'Million Dollars, But... The Game Announcement',
 | 
			
		||||
        },
 | 
			
		||||
        'skip_download': 'm3u8',
 | 
			
		||||
        'params': {'skip_download': True},
 | 
			
		||||
    }, {
 | 
			
		||||
        'url': 'https://roosterteeth.com/watch/rwby-bonus-25',
 | 
			
		||||
        'info_dict': {
 | 
			
		||||
@@ -112,7 +112,7 @@ class RoosterTeethIE(RoosterTeethBaseIE):
 | 
			
		||||
            'thumbnail': r're:^https?://.*\.(png|jpe?g)$',
 | 
			
		||||
            'ext': 'mp4',
 | 
			
		||||
        },
 | 
			
		||||
        'skip_download': 'm3u8',
 | 
			
		||||
        'params': {'skip_download': True},
 | 
			
		||||
    }, {
 | 
			
		||||
        'url': 'http://achievementhunter.roosterteeth.com/episode/off-topic-the-achievement-hunter-podcast-2016-i-didn-t-think-it-would-pass-31',
 | 
			
		||||
        'only_matching': True,
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,7 @@ class SoundcloudBaseIE(InfoExtractor):
 | 
			
		||||
        elif username is not None:
 | 
			
		||||
            self.report_warning(
 | 
			
		||||
                'Login using username and password is not currently supported. '
 | 
			
		||||
                'Use "--user oauth --password <oauth_token>" to login using an oauth token')
 | 
			
		||||
                'Use "--username oauth --password <oauth_token>" to login using an oauth token')
 | 
			
		||||
 | 
			
		||||
        r'''
 | 
			
		||||
        def genDevId():
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,10 @@ from ..compat import compat_str
 | 
			
		||||
from ..utils import (
 | 
			
		||||
    ExtractorError,
 | 
			
		||||
    smuggle_url,
 | 
			
		||||
    str_or_none,
 | 
			
		||||
    traverse_obj,
 | 
			
		||||
    unsmuggle_url,
 | 
			
		||||
    unified_strdate,
 | 
			
		||||
    unsmuggle_url,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
import itertools
 | 
			
		||||
@@ -25,9 +26,9 @@ class VoicyBaseIE(InfoExtractor):
 | 
			
		||||
            'id': voice_id,
 | 
			
		||||
            'title': compat_str(value.get('PlaylistName')),
 | 
			
		||||
            'uploader': value.get('SpeakerName'),
 | 
			
		||||
            'uploader_id': compat_str(value.get('SpeakerId')),
 | 
			
		||||
            'uploader_id': str_or_none(value.get('SpeakerId')),
 | 
			
		||||
            'channel': value.get('ChannelName'),
 | 
			
		||||
            'channel_id': compat_str(value.get('ChannelId')),
 | 
			
		||||
            'channel_id': str_or_none(value.get('ChannelId')),
 | 
			
		||||
            'upload_date': upload_date,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -668,7 +668,7 @@ def parseOpts(overrideArguments=None):
 | 
			
		||||
    downloader.add_option(
 | 
			
		||||
        '-N', '--concurrent-fragments',
 | 
			
		||||
        dest='concurrent_fragment_downloads', metavar='N', default=1, type=int,
 | 
			
		||||
        help='Number of fragments of a dash/hlsnative video that should be download concurrently (default is %default)')
 | 
			
		||||
        help='Number of fragments of a dash/hlsnative video that should be downloaded concurrently (default is %default)')
 | 
			
		||||
    downloader.add_option(
 | 
			
		||||
        '-r', '--limit-rate', '--rate-limit',
 | 
			
		||||
        dest='ratelimit', metavar='RATE',
 | 
			
		||||
 
 | 
			
		||||
@@ -99,7 +99,7 @@ class MetadataParserPP(PostProcessor):
 | 
			
		||||
class MetadataFromFieldPP(MetadataParserPP):
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def to_action(cls, f):
 | 
			
		||||
        match = re.match(r'(?P<in>.*?)(?<!\\):(?P<out>.+)$', f)
 | 
			
		||||
        match = re.match(r'(?s)(?P<in>.*?)(?<!\\):(?P<out>.+)$', f)
 | 
			
		||||
        if match is None:
 | 
			
		||||
            raise ValueError(f'it should be FROM:TO, not {f!r}')
 | 
			
		||||
        return (
 | 
			
		||||
 
 | 
			
		||||
@@ -257,7 +257,7 @@ def update_self(to_screen, verbose, opener):
 | 
			
		||||
 | 
			
		||||
    write_string(
 | 
			
		||||
        'DeprecationWarning: "yt_dlp.update.update_self" is deprecated and may be removed in a future version. '
 | 
			
		||||
        'Use "yt_dlp.update.run_update(ydl)" instead')
 | 
			
		||||
        'Use "yt_dlp.update.run_update(ydl)" instead\n')
 | 
			
		||||
 | 
			
		||||
    class FakeYDL():
 | 
			
		||||
        _opener = opener
 | 
			
		||||
 
 | 
			
		||||
@@ -1862,7 +1862,6 @@ def _windows_write_string(s, out):
 | 
			
		||||
    False if it has yet to be written out."""
 | 
			
		||||
    # Adapted from http://stackoverflow.com/a/3259271/35070
 | 
			
		||||
 | 
			
		||||
    import ctypes
 | 
			
		||||
    import ctypes.wintypes
 | 
			
		||||
 | 
			
		||||
    WIN_OUTPUT_IDS = {
 | 
			
		||||
@@ -3193,30 +3192,29 @@ def parse_codecs(codecs_str):
 | 
			
		||||
        if codec in ('avc1', 'avc2', 'avc3', 'avc4', 'vp9', 'vp8', 'hev1', 'hev2',
 | 
			
		||||
                     'h263', 'h264', 'mp4v', 'hvc1', 'av1', 'theora', 'dvh1', 'dvhe'):
 | 
			
		||||
            if not vcodec:
 | 
			
		||||
                vcodec = '.'.join(parts[:4]) if codec in ('vp9', 'av1') else full_codec
 | 
			
		||||
                vcodec = '.'.join(parts[:4]) if codec in ('vp9', 'av1', 'hvc1') else full_codec
 | 
			
		||||
                if codec in ('dvh1', 'dvhe'):
 | 
			
		||||
                    hdr = 'DV'
 | 
			
		||||
                elif codec == 'av1' and len(parts) > 3 and parts[3] == '10':
 | 
			
		||||
                    hdr = 'HDR10'
 | 
			
		||||
                elif full_codec.replace('0', '').startswith('vp9.2'):
 | 
			
		||||
                    hdr = 'HDR10'
 | 
			
		||||
        elif codec in ('mp4a', 'opus', 'vorbis', 'mp3', 'aac', 'ac-3', 'ec-3', 'eac3', 'dtsc', 'dtse', 'dtsh', 'dtsl'):
 | 
			
		||||
        elif codec in ('flac', 'mp4a', 'opus', 'vorbis', 'mp3', 'aac', 'ac-3', 'ec-3', 'eac3', 'dtsc', 'dtse', 'dtsh', 'dtsl'):
 | 
			
		||||
            if not acodec:
 | 
			
		||||
                acodec = full_codec
 | 
			
		||||
        else:
 | 
			
		||||
            write_string('WARNING: Unknown codec %s\n' % full_codec, sys.stderr)
 | 
			
		||||
    if not vcodec and not acodec:
 | 
			
		||||
        if len(split_codecs) == 2:
 | 
			
		||||
            return {
 | 
			
		||||
                'vcodec': split_codecs[0],
 | 
			
		||||
                'acodec': split_codecs[1],
 | 
			
		||||
            }
 | 
			
		||||
    else:
 | 
			
		||||
    if vcodec or acodec:
 | 
			
		||||
        return {
 | 
			
		||||
            'vcodec': vcodec or 'none',
 | 
			
		||||
            'acodec': acodec or 'none',
 | 
			
		||||
            'dynamic_range': hdr,
 | 
			
		||||
        }
 | 
			
		||||
    elif len(split_codecs) == 2:
 | 
			
		||||
        return {
 | 
			
		||||
            'vcodec': split_codecs[0],
 | 
			
		||||
            'acodec': split_codecs[1],
 | 
			
		||||
        }
 | 
			
		||||
    return {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user