mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-06-28 01:18:30 +00:00
Merge 386132ba25
into 73bf102116
This commit is contained in:
commit
fb7e23606e
@ -2349,7 +2349,7 @@ #### Developer options
|
|||||||
--test Download only part of video for testing extractors
|
--test Download only part of video for testing extractors
|
||||||
--load-pages Load pages dumped by --write-pages
|
--load-pages Load pages dumped by --write-pages
|
||||||
--youtube-print-sig-code For testing youtube signatures
|
--youtube-print-sig-code For testing youtube signatures
|
||||||
--allow-unplayable-formats List unplayable formats also
|
--allow-unplayable-formats List unplayable formats. Implies `--simulate` and `--list-formats`.
|
||||||
--no-allow-unplayable-formats Default
|
--no-allow-unplayable-formats Default
|
||||||
|
|
||||||
#### Old aliases
|
#### Old aliases
|
||||||
|
@ -248,7 +248,7 @@ class YoutubeDL:
|
|||||||
You can also pass a function. The function takes 'ctx' as
|
You can also pass a function. The function takes 'ctx' as
|
||||||
argument and returns the formats to download.
|
argument and returns the formats to download.
|
||||||
See "build_format_selector" for an implementation
|
See "build_format_selector" for an implementation
|
||||||
allow_unplayable_formats: Allow unplayable formats to be extracted and downloaded.
|
allow_unplayable_formats: Allow unplayable formats to be extracted.
|
||||||
ignore_no_formats_error: Ignore "No video formats" error. Usefull for
|
ignore_no_formats_error: Ignore "No video formats" error. Usefull for
|
||||||
extracting metadata even if the video is not actually
|
extracting metadata even if the video is not actually
|
||||||
available for download (experimental)
|
available for download (experimental)
|
||||||
@ -702,11 +702,14 @@ def process_color_policy(stream):
|
|||||||
self.deprecated_feature(system_deprecation.replace('\n', '\n '))
|
self.deprecated_feature(system_deprecation.replace('\n', '\n '))
|
||||||
|
|
||||||
if self.params.get('allow_unplayable_formats'):
|
if self.params.get('allow_unplayable_formats'):
|
||||||
|
from . import _IN_CLI
|
||||||
|
|
||||||
|
switch = '--allow-unplayable-formats' if _IN_CLI else 'allow_unplayable_formats'
|
||||||
self.report_warning(
|
self.report_warning(
|
||||||
f'You have asked for {self._format_err("UNPLAYABLE", self.Styles.EMPHASIS)} formats to be listed/downloaded. '
|
f'{switch} is a {self._format_err("developer option", self.Styles.EMPHASIS)} intended for {self._format_err("debugging", self.Styles.EMPHASIS)}. \n'
|
||||||
'This is a developer option intended for debugging. \n'
|
f' If you experience issues {self._format_err("DO NOT", self.Styles.ERROR)} open a bug report.')
|
||||||
' If you experience any issues while using this option, '
|
self.params['listformats'] = True
|
||||||
f'{self._format_err("DO NOT", self.Styles.ERROR)} open a bug report')
|
self.params['simulate'] = True
|
||||||
|
|
||||||
if self.params.get('bidi_workaround', False):
|
if self.params.get('bidi_workaround', False):
|
||||||
try:
|
try:
|
||||||
@ -2849,6 +2852,7 @@ def sanitize_numeric_fields(info):
|
|||||||
info_dict['_has_drm'] = any( # or None ensures --clean-infojson removes it
|
info_dict['_has_drm'] = any( # or None ensures --clean-infojson removes it
|
||||||
f.get('has_drm') and f['has_drm'] != 'maybe' for f in formats) or None
|
f.get('has_drm') and f['has_drm'] != 'maybe' for f in formats) or None
|
||||||
if not self.params.get('allow_unplayable_formats'):
|
if not self.params.get('allow_unplayable_formats'):
|
||||||
|
# Allow bypassing flaky `has_drm` detection
|
||||||
formats = [f for f in formats if not f.get('has_drm') or f['has_drm'] == 'maybe']
|
formats = [f for f in formats if not f.get('has_drm') or f['has_drm'] == 'maybe']
|
||||||
|
|
||||||
if formats and all(f.get('acodec') == f.get('vcodec') == 'none' for f in formats):
|
if formats and all(f.get('acodec') == f.get('vcodec') == 'none' for f in formats):
|
||||||
@ -3464,12 +3468,7 @@ def correct_ext(filename, ext=new_ext):
|
|||||||
success, real_download = self.dl(temp_filename, info_dict)
|
success, real_download = self.dl(temp_filename, info_dict)
|
||||||
info_dict['__real_download'] = real_download
|
info_dict['__real_download'] = real_download
|
||||||
else:
|
else:
|
||||||
if self.params.get('allow_unplayable_formats'):
|
if not merger.available:
|
||||||
self.report_warning(
|
|
||||||
'You have requested merging of multiple formats '
|
|
||||||
'while also allowing unplayable formats to be downloaded. '
|
|
||||||
'The formats won\'t be merged to prevent data corruption.')
|
|
||||||
elif not merger.available:
|
|
||||||
msg = 'You have requested merging of multiple formats but ffmpeg is not installed'
|
msg = 'You have requested merging of multiple formats but ffmpeg is not installed'
|
||||||
if not self.params.get('ignoreerrors'):
|
if not self.params.get('ignoreerrors'):
|
||||||
self.report_error(f'{msg}. Aborting due to --abort-on-error')
|
self.report_error(f'{msg}. Aborting due to --abort-on-error')
|
||||||
@ -3500,7 +3499,7 @@ def correct_ext(filename, ext=new_ext):
|
|||||||
info_dict['__real_download'] = info_dict['__real_download'] or real_download
|
info_dict['__real_download'] = info_dict['__real_download'] or real_download
|
||||||
success = success and partial_success
|
success = success and partial_success
|
||||||
|
|
||||||
if downloaded and merger.available and not self.params.get('allow_unplayable_formats'):
|
if downloaded and merger.available:
|
||||||
info_dict['__postprocessors'].append(merger)
|
info_dict['__postprocessors'].append(merger)
|
||||||
info_dict['__files_to_merge'] = downloaded
|
info_dict['__files_to_merge'] = downloaded
|
||||||
# Even if there were no downloads, it is being merged only now
|
# Even if there were no downloads, it is being merged only now
|
||||||
|
@ -511,8 +511,7 @@ def report_args_compat(name, value, key1, key2=None, where=None):
|
|||||||
opts.postprocessor_args['default'] = opts.postprocessor_args.pop('default-compat')
|
opts.postprocessor_args['default'] = opts.postprocessor_args.pop('default-compat')
|
||||||
opts.postprocessor_args.setdefault('sponskrub', [])
|
opts.postprocessor_args.setdefault('sponskrub', [])
|
||||||
|
|
||||||
def report_conflict(arg1, opt1, arg2='--allow-unplayable-formats', opt2='allow_unplayable_formats',
|
def report_conflict(arg1, opt1, arg2, opt2, val1=NO_DEFAULT, val2=NO_DEFAULT, default=False):
|
||||||
val1=NO_DEFAULT, val2=NO_DEFAULT, default=False):
|
|
||||||
if val2 is NO_DEFAULT:
|
if val2 is NO_DEFAULT:
|
||||||
val2 = getattr(opts, opt2)
|
val2 = getattr(opts, opt2)
|
||||||
if not val2:
|
if not val2:
|
||||||
@ -540,21 +539,6 @@ def report_conflict(arg1, opt1, arg2='--allow-unplayable-formats', opt2='allow_u
|
|||||||
report_conflict('--sponskrub-cut', 'sponskrub_cut', '--split-chapter', 'split_chapters',
|
report_conflict('--sponskrub-cut', 'sponskrub_cut', '--split-chapter', 'split_chapters',
|
||||||
val1=opts.sponskrub and opts.sponskrub_cut)
|
val1=opts.sponskrub and opts.sponskrub_cut)
|
||||||
|
|
||||||
# Conflicts with --allow-unplayable-formats
|
|
||||||
report_conflict('--embed-metadata', 'addmetadata')
|
|
||||||
report_conflict('--embed-chapters', 'addchapters')
|
|
||||||
report_conflict('--embed-info-json', 'embed_infojson')
|
|
||||||
report_conflict('--embed-subs', 'embedsubtitles')
|
|
||||||
report_conflict('--embed-thumbnail', 'embedthumbnail')
|
|
||||||
report_conflict('--extract-audio', 'extractaudio')
|
|
||||||
report_conflict('--fixup', 'fixup', val1=opts.fixup not in (None, 'never', 'ignore'), default='never')
|
|
||||||
report_conflict('--recode-video', 'recodevideo')
|
|
||||||
report_conflict('--remove-chapters', 'remove_chapters', default=[])
|
|
||||||
report_conflict('--remux-video', 'remuxvideo')
|
|
||||||
report_conflict('--sponskrub', 'sponskrub')
|
|
||||||
report_conflict('--sponsorblock-remove', 'sponsorblock_remove', default=set())
|
|
||||||
report_conflict('--xattrs', 'xattrs')
|
|
||||||
|
|
||||||
# Fully deprecated options
|
# Fully deprecated options
|
||||||
def report_deprecation(val, old, new=None):
|
def report_deprecation(val, old, new=None):
|
||||||
if not val:
|
if not val:
|
||||||
|
@ -468,7 +468,6 @@ def can_merge_formats(cls, info_dict, params):
|
|||||||
return (
|
return (
|
||||||
info_dict.get('requested_formats')
|
info_dict.get('requested_formats')
|
||||||
and info_dict.get('protocol')
|
and info_dict.get('protocol')
|
||||||
and not params.get('allow_unplayable_formats')
|
|
||||||
and 'no-direct-merge' not in params.get('compat_opts', [])
|
and 'no-direct-merge' not in params.get('compat_opts', [])
|
||||||
and cls.can_download(info_dict))
|
and cls.can_download(info_dict))
|
||||||
|
|
||||||
|
@ -256,7 +256,6 @@ def _get_unencrypted_media(self, doc):
|
|||||||
media = doc.findall(_add_ns('media'))
|
media = doc.findall(_add_ns('media'))
|
||||||
if not media:
|
if not media:
|
||||||
self.report_error('No media found')
|
self.report_error('No media found')
|
||||||
if not self.params.get('allow_unplayable_formats'):
|
|
||||||
for e in (doc.findall(_add_ns('drmAdditionalHeader'))
|
for e in (doc.findall(_add_ns('drmAdditionalHeader'))
|
||||||
+ doc.findall(_add_ns('drmAdditionalHeaderSet'))):
|
+ doc.findall(_add_ns('drmAdditionalHeaderSet'))):
|
||||||
# If id attribute is missing it's valid for all media nodes
|
# If id attribute is missing it's valid for all media nodes
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
traverse_obj,
|
traverse_obj,
|
||||||
update_url_query,
|
update_url_query,
|
||||||
urljoin,
|
urljoin,
|
||||||
|
deprecation_warning,
|
||||||
)
|
)
|
||||||
from ..utils._utils import _request_dump_filename
|
from ..utils._utils import _request_dump_filename
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ def _has_drm(manifest): # TODO: https://github.com/yt-dlp/yt-dlp/pull/5039
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_download(cls, manifest, info_dict, allow_unplayable_formats=False):
|
def can_download(cls, manifest, info_dict, allow_unplayable_formats=False):
|
||||||
|
if allow_unplayable_formats:
|
||||||
|
deprecation_warning('allow_unplayable_formats is not supported', stacklevel=1)
|
||||||
UNSUPPORTED_FEATURES = [
|
UNSUPPORTED_FEATURES = [
|
||||||
# r'#EXT-X-BYTERANGE', # playlists composed of byte ranges of media files [2]
|
# r'#EXT-X-BYTERANGE', # playlists composed of byte ranges of media files [2]
|
||||||
|
|
||||||
@ -58,7 +61,6 @@ def can_download(cls, manifest, info_dict, allow_unplayable_formats=False):
|
|||||||
# 4. https://tools.ietf.org/html/draft-pantos-http-live-streaming-17#section-4.3.3.5
|
# 4. https://tools.ietf.org/html/draft-pantos-http-live-streaming-17#section-4.3.3.5
|
||||||
# 5. https://tools.ietf.org/html/draft-pantos-http-live-streaming-17#section-4.3.2.5
|
# 5. https://tools.ietf.org/html/draft-pantos-http-live-streaming-17#section-4.3.2.5
|
||||||
]
|
]
|
||||||
if not allow_unplayable_formats:
|
|
||||||
UNSUPPORTED_FEATURES += [
|
UNSUPPORTED_FEATURES += [
|
||||||
r'#EXT-X-KEY:METHOD=(?!NONE|AES-128)', # encrypted streams [1], but not necessarily DRM
|
r'#EXT-X-KEY:METHOD=(?!NONE|AES-128)', # encrypted streams [1], but not necessarily DRM
|
||||||
]
|
]
|
||||||
@ -67,7 +69,6 @@ def check_results():
|
|||||||
yield not info_dict.get('is_live')
|
yield not info_dict.get('is_live')
|
||||||
for feature in UNSUPPORTED_FEATURES:
|
for feature in UNSUPPORTED_FEATURES:
|
||||||
yield not re.search(feature, manifest)
|
yield not re.search(feature, manifest)
|
||||||
if not allow_unplayable_formats:
|
|
||||||
yield not cls._has_drm(manifest)
|
yield not cls._has_drm(manifest)
|
||||||
return all(check_results())
|
return all(check_results())
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ def real_download(self, filename, info_dict):
|
|||||||
outf.write(s_bytes)
|
outf.write(s_bytes)
|
||||||
s = s_bytes.decode('utf-8', 'ignore')
|
s = s_bytes.decode('utf-8', 'ignore')
|
||||||
|
|
||||||
can_download, message = self.can_download(s, info_dict, self.params.get('allow_unplayable_formats')), None
|
can_download, message = self.can_download(s, info_dict), None
|
||||||
if can_download:
|
if can_download:
|
||||||
has_ffmpeg = FFmpegFD.available()
|
has_ffmpeg = FFmpegFD.available()
|
||||||
no_crypto = not Cryptodome.AES and '#EXT-X-KEY:METHOD=AES-128' in s
|
no_crypto = not Cryptodome.AES and '#EXT-X-KEY:METHOD=AES-128' in s
|
||||||
@ -105,7 +106,7 @@ def real_download(self, filename, info_dict):
|
|||||||
message = ('Live HLS streams are not supported by the native downloader. If this is a livestream, '
|
message = ('Live HLS streams are not supported by the native downloader. If this is a livestream, '
|
||||||
f'please {install_ffmpeg}add "--downloader ffmpeg --hls-use-mpegts" to your command')
|
f'please {install_ffmpeg}add "--downloader ffmpeg --hls-use-mpegts" to your command')
|
||||||
if not can_download:
|
if not can_download:
|
||||||
if self._has_drm(s) and not self.params.get('allow_unplayable_formats'):
|
if self._has_drm(s):
|
||||||
if info_dict.get('has_drm') and self.params.get('test'):
|
if info_dict.get('has_drm') and self.params.get('test'):
|
||||||
self.to_screen(f'[{self.FD_NAME}] This format is DRM protected', skip_eol=True)
|
self.to_screen(f'[{self.FD_NAME}] This format is DRM protected', skip_eol=True)
|
||||||
else:
|
else:
|
||||||
|
@ -236,7 +236,7 @@ def _real_extract(self, url):
|
|||||||
self._call_api_v1(
|
self._call_api_v1(
|
||||||
f'{video_type}/detail', video_id, fatal=False, query={'tas': 10000, 'contentId': video_id}),
|
f'{video_type}/detail', video_id, fatal=False, query={'tas': 10000, 'contentId': video_id}),
|
||||||
('body', 'results', 'item', {dict})) or {}
|
('body', 'results', 'item', {dict})) or {}
|
||||||
if not self.get_param('allow_unplayable_formats') and video_data.get('drmProtected'):
|
if video_data.get('drmProtected'):
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
|
|
||||||
# See https://github.com/yt-dlp/yt-dlp/issues/396
|
# See https://github.com/yt-dlp/yt-dlp/issues/396
|
||||||
|
@ -140,13 +140,14 @@ def _real_extract(self, url):
|
|||||||
quality = qualities(self._KNOWN_FORMATS)
|
quality = qualities(self._KNOWN_FORMATS)
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
|
has_drm = False
|
||||||
for f in result.get('files', []):
|
for f in result.get('files', []):
|
||||||
f_url = f.get('url')
|
f_url = f.get('url')
|
||||||
content_format = f.get('content_format')
|
content_format = f.get('content_format')
|
||||||
if not f_url:
|
if not f_url:
|
||||||
continue
|
continue
|
||||||
if (not self.get_param('allow_unplayable_formats')
|
if '-MDRM-' in content_format or '-FPS-' in content_format:
|
||||||
and ('-MDRM-' in content_format or '-FPS-' in content_format)):
|
has_drm = True
|
||||||
continue
|
continue
|
||||||
formats.append({
|
formats.append({
|
||||||
'url': f_url,
|
'url': f_url,
|
||||||
@ -154,6 +155,8 @@ def _real_extract(self, url):
|
|||||||
'quality': quality(content_format),
|
'quality': quality(content_format),
|
||||||
'filesize': int_or_none(f.get('size_in_bytes')),
|
'filesize': int_or_none(f.get('size_in_bytes')),
|
||||||
})
|
})
|
||||||
|
if not formats and has_drm:
|
||||||
|
self.report_drm(video_id)
|
||||||
|
|
||||||
compilation = result.get('compilation')
|
compilation = result.get('compilation')
|
||||||
episode = title if compilation else None
|
episode = title if compilation else None
|
||||||
|
@ -464,6 +464,7 @@ def sign_url(unsigned_url):
|
|||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
subtitles = {}
|
subtitles = {}
|
||||||
|
has_drm = False
|
||||||
for f in flavor_assets:
|
for f in flavor_assets:
|
||||||
# Continue if asset is not ready
|
# Continue if asset is not ready
|
||||||
if f.get('status') != 2:
|
if f.get('status') != 2:
|
||||||
@ -473,7 +474,8 @@ def sign_url(unsigned_url):
|
|||||||
if f.get('fileExt') == 'chun':
|
if f.get('fileExt') == 'chun':
|
||||||
continue
|
continue
|
||||||
# DRM-protected video, cannot be decrypted
|
# DRM-protected video, cannot be decrypted
|
||||||
if not self.get_param('allow_unplayable_formats') and f.get('fileExt') == 'wvm':
|
if f.get('fileExt') == 'wvm':
|
||||||
|
has_drm = True
|
||||||
continue
|
continue
|
||||||
if not f.get('fileExt'):
|
if not f.get('fileExt'):
|
||||||
# QT indicates QuickTime; some videos have broken fileExt
|
# QT indicates QuickTime; some videos have broken fileExt
|
||||||
@ -513,6 +515,9 @@ def sign_url(unsigned_url):
|
|||||||
formats.extend(fmts)
|
formats.extend(fmts)
|
||||||
self._merge_subtitles(subs, target=subtitles)
|
self._merge_subtitles(subs, target=subtitles)
|
||||||
|
|
||||||
|
if not formats and has_drm:
|
||||||
|
self.report_drm(entry_id)
|
||||||
|
|
||||||
if captions:
|
if captions:
|
||||||
for caption in captions.get('objects', []):
|
for caption in captions.get('objects', []):
|
||||||
# Continue if caption is not ready
|
# Continue if caption is not ready
|
||||||
|
@ -91,11 +91,13 @@ def _extract_info(self, pc, mobile, i, referer):
|
|||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
urls = []
|
urls = []
|
||||||
|
has_drm = False
|
||||||
for stream in pc_item.get('streams', []):
|
for stream in pc_item.get('streams', []):
|
||||||
stream_url = stream.get('url')
|
stream_url = stream.get('url')
|
||||||
if not stream_url or stream_url in urls:
|
if not stream_url or stream_url in urls:
|
||||||
continue
|
continue
|
||||||
if not self.get_param('allow_unplayable_formats') and stream.get('drmProtected'):
|
if stream.get('drmProtected'):
|
||||||
|
has_drm = True
|
||||||
continue
|
continue
|
||||||
urls.append(stream_url)
|
urls.append(stream_url)
|
||||||
ext = determine_ext(stream_url)
|
ext = determine_ext(stream_url)
|
||||||
@ -159,8 +161,8 @@ def _extract_info(self, pc, mobile, i, referer):
|
|||||||
format_id = mobile_url.get('targetMediaPlatform')
|
format_id = mobile_url.get('targetMediaPlatform')
|
||||||
if not media_url or media_url in urls:
|
if not media_url or media_url in urls:
|
||||||
continue
|
continue
|
||||||
if (format_id in ('Widevine', 'SmoothStreaming')
|
if format_id in ('Widevine', 'SmoothStreaming'):
|
||||||
and not self.get_param('allow_unplayable_formats', False)):
|
has_drm = True
|
||||||
continue
|
continue
|
||||||
urls.append(media_url)
|
urls.append(media_url)
|
||||||
ext = determine_ext(media_url)
|
ext = determine_ext(media_url)
|
||||||
@ -179,6 +181,9 @@ def _extract_info(self, pc, mobile, i, referer):
|
|||||||
'ext': ext,
|
'ext': ext,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if not formats and has_drm:
|
||||||
|
self.report_drm(video_id)
|
||||||
|
|
||||||
subtitles = {}
|
subtitles = {}
|
||||||
for flag in mobile_item.get('flags'):
|
for flag in mobile_item.get('flags'):
|
||||||
if flag == 'ClosedCaptions':
|
if flag == 'ClosedCaptions':
|
||||||
|
@ -29,8 +29,7 @@ def _real_extract(self, url):
|
|||||||
'$include': '[HasClosedCaptions]',
|
'$include': '[HasClosedCaptions]',
|
||||||
})
|
})
|
||||||
|
|
||||||
if (not self.get_param('allow_unplayable_formats')
|
if try_get(content_package, lambda x: x['Constraints']['Security']['Type']):
|
||||||
and try_get(content_package, lambda x: x['Constraints']['Security']['Type'])):
|
|
||||||
self.report_drm(content_id)
|
self.report_drm(content_id)
|
||||||
|
|
||||||
manifest_base_url = content_package_url + 'manifest.'
|
manifest_base_url = content_package_url + 'manifest.'
|
||||||
|
@ -65,8 +65,7 @@ def process_format_list(format_list, format_id=''):
|
|||||||
for format_dict in format_list:
|
for format_dict in format_list:
|
||||||
if not isinstance(format_dict, dict):
|
if not isinstance(format_dict, dict):
|
||||||
continue
|
continue
|
||||||
if (not self.get_param('allow_unplayable_formats')
|
if traverse_obj(format_dict, ('drm', 'keySystem')):
|
||||||
and traverse_obj(format_dict, ('drm', 'keySystem'))):
|
|
||||||
has_drm = True
|
has_drm = True
|
||||||
continue
|
continue
|
||||||
format_url = url_or_none(format_dict.get('src'))
|
format_url = url_or_none(format_dict.get('src'))
|
||||||
|
@ -275,8 +275,7 @@ def _real_extract(self, url):
|
|||||||
'url': stream_url,
|
'url': stream_url,
|
||||||
})
|
})
|
||||||
|
|
||||||
if not formats:
|
if not formats and drm:
|
||||||
if not self.get_param('allow_unplayable_formats') and drm:
|
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
|
@ -31,7 +31,7 @@ def _extract_video_info(self, url, clip_id):
|
|||||||
'ids': clip_id,
|
'ids': clip_id,
|
||||||
})[0]
|
})[0]
|
||||||
|
|
||||||
if not self.get_param('allow_unplayable_formats') and video.get('is_protected') is True:
|
if video.get('is_protected') is True:
|
||||||
self.report_drm(clip_id)
|
self.report_drm(clip_id)
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
|
@ -337,8 +337,12 @@ def _real_extract(self, url):
|
|||||||
'height': height,
|
'height': height,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
has_drm = False
|
||||||
mpd_url = None if data.get('isLive') else data.get('urlDash')
|
mpd_url = None if data.get('isLive') else data.get('urlDash')
|
||||||
if mpd_url and (self.get_param('allow_unplayable_formats') or not data.get('drm')):
|
if mpd_url:
|
||||||
|
if data.get('drm'):
|
||||||
|
has_drm = True
|
||||||
|
else:
|
||||||
fmts, subs = self._extract_mpd_formats_and_subtitles(
|
fmts, subs = self._extract_mpd_formats_and_subtitles(
|
||||||
mpd_url, media_id, mpd_id='dash', fatal=False)
|
mpd_url, media_id, mpd_id='dash', fatal=False)
|
||||||
formats.extend(fmts)
|
formats.extend(fmts)
|
||||||
@ -365,6 +369,9 @@ def _real_extract(self, url):
|
|||||||
formats.extend(fmts)
|
formats.extend(fmts)
|
||||||
self._merge_subtitles(subs, target=subtitles)
|
self._merge_subtitles(subs, target=subtitles)
|
||||||
|
|
||||||
|
if not formats and has_drm:
|
||||||
|
self.report_drm(media_id)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': media_id,
|
'id': media_id,
|
||||||
'formats': formats,
|
'formats': formats,
|
||||||
|
@ -237,8 +237,7 @@ def pv(name):
|
|||||||
return value or None
|
return value or None
|
||||||
|
|
||||||
if not formats:
|
if not formats:
|
||||||
if (not self.get_param('allow_unplayable_formats')
|
if xpath_text(video_xml, './Clip/DRM', default=None):
|
||||||
and xpath_text(video_xml, './Clip/DRM', default=None)):
|
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
ns_st_cds = pv('ns_st_cds')
|
ns_st_cds = pv('ns_st_cds')
|
||||||
if ns_st_cds != 'free':
|
if ns_st_cds != 'free':
|
||||||
|
@ -111,7 +111,7 @@ def _real_extract(self, url):
|
|||||||
playout = self._call_api(
|
playout = self._call_api(
|
||||||
'playout/new/url/' + video_id, video_id)['playout']
|
'playout/new/url/' + video_id, video_id)['playout']
|
||||||
|
|
||||||
if not self.get_param('allow_unplayable_formats') and playout.get('drm'):
|
if playout.get('drm'):
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
|
|
||||||
formats = self._extract_m3u8_formats(re.sub(
|
formats = self._extract_m3u8_formats(re.sub(
|
||||||
|
@ -142,7 +142,7 @@ def _real_extract(self, url):
|
|||||||
video_id = self._match_id(url)
|
video_id = self._match_id(url)
|
||||||
content = self._call_api(
|
content = self._call_api(
|
||||||
'1.5', 'IN/CONTENT/VIDEOURL/VOD/' + video_id, video_id)
|
'1.5', 'IN/CONTENT/VIDEOURL/VOD/' + video_id, video_id)
|
||||||
if not self.get_param('allow_unplayable_formats') and content.get('isEncrypted'):
|
if content.get('isEncrypted'):
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
dash_url = content['videoURL']
|
dash_url = content['videoURL']
|
||||||
headers = {
|
headers = {
|
||||||
|
@ -126,8 +126,7 @@ def _real_extract(self, url):
|
|||||||
})
|
})
|
||||||
if not formats:
|
if not formats:
|
||||||
for meta in (info.get('Metas') or []):
|
for meta in (info.get('Metas') or []):
|
||||||
if (not self.get_param('allow_unplayable_formats')
|
if meta.get('Key') == 'Encryption' and meta.get('Value') == '1':
|
||||||
and meta.get('Key') == 'Encryption' and meta.get('Value') == '1'):
|
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
# Most likely because geo-blocked if no formats and no DRM
|
# Most likely because geo-blocked if no formats and no DRM
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ def _real_extract(self, url):
|
|||||||
})
|
})
|
||||||
# IsDrm does not necessarily mean the video is DRM protected (see
|
# IsDrm does not necessarily mean the video is DRM protected (see
|
||||||
# https://github.com/ytdl-org/youtube-dl/issues/13994).
|
# https://github.com/ytdl-org/youtube-dl/issues/13994).
|
||||||
if not self.get_param('allow_unplayable_formats') and metadata.get('IsDrm'):
|
if metadata.get('IsDrm'):
|
||||||
self.report_warning('This video is probably DRM protected.', path)
|
self.report_warning('This video is probably DRM protected.', path)
|
||||||
video_id = metadata['IdMedia']
|
video_id = metadata['IdMedia']
|
||||||
details = metadata['Details']
|
details = metadata['Details']
|
||||||
|
@ -261,7 +261,6 @@ def _real_extract(self, url):
|
|||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
if stream_meta.get('is_drm'):
|
if stream_meta.get('is_drm'):
|
||||||
if not self.get_param('allow_unplayable_formats'):
|
|
||||||
self.report_drm(video_id)
|
self.report_drm(video_id)
|
||||||
if stream_meta.get('is_premium'):
|
if stream_meta.get('is_premium'):
|
||||||
sources = self._download_json(
|
sources = self._download_json(
|
||||||
|
7812
yt_dlp/extractor/youtube.py
Normal file
7812
yt_dlp/extractor/youtube.py
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user