mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-08-01 01:58:28 +00:00
Merge branch 'yt-dlp:master' into master
This commit is contained in:
commit
d26bb251cc
@ -94,12 +94,19 @@ def real_download(self, filename, info_dict):
|
|||||||
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, self.params.get('allow_unplayable_formats')), 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
|
if not Cryptodome.AES and '#EXT-X-KEY:METHOD=AES-128' in s:
|
||||||
if no_crypto and has_ffmpeg:
|
# Even if pycryptodomex isn't available, force HlsFD for m3u8s that won't work with ffmpeg
|
||||||
can_download, message = False, 'The stream has AES-128 encryption and pycryptodomex is not available'
|
ffmpeg_can_dl = not traverse_obj(info_dict, ((
|
||||||
elif no_crypto:
|
'extra_param_to_segment_url', 'extra_param_to_key_url',
|
||||||
message = ('The stream has AES-128 encryption and neither ffmpeg nor pycryptodomex are available; '
|
'hls_media_playlist_data', ('hls_aes', ('uri', 'key', 'iv')),
|
||||||
'Decryption will be performed natively, but will be extremely slow')
|
), any))
|
||||||
|
message = 'The stream has AES-128 encryption and {} available'.format(
|
||||||
|
'neither ffmpeg nor pycryptodomex are' if ffmpeg_can_dl and not has_ffmpeg else
|
||||||
|
'pycryptodomex is not')
|
||||||
|
if has_ffmpeg and ffmpeg_can_dl:
|
||||||
|
can_download = False
|
||||||
|
else:
|
||||||
|
message += '; decryption will be performed natively, but will be extremely slow'
|
||||||
elif info_dict.get('extractor_key') == 'Generic' and re.search(r'(?m)#EXT-X-MEDIA-SEQUENCE:(?!0$)', s):
|
elif info_dict.get('extractor_key') == 'Generic' and re.search(r'(?m)#EXT-X-MEDIA-SEQUENCE:(?!0$)', s):
|
||||||
install_ffmpeg = '' if has_ffmpeg else 'install ffmpeg and '
|
install_ffmpeg = '' if has_ffmpeg else 'install ffmpeg and '
|
||||||
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, '
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..networking.exceptions import HTTPError
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
UserNotLive,
|
UserNotLive,
|
||||||
@ -188,19 +189,39 @@ def _get_thumbnails(self, thumbnail):
|
|||||||
}] if thumbnail else None
|
}] if thumbnail else None
|
||||||
|
|
||||||
def _extract_twitch_m3u8_formats(self, path, video_id, token, signature, live_from_start=False):
|
def _extract_twitch_m3u8_formats(self, path, video_id, token, signature, live_from_start=False):
|
||||||
formats = self._extract_m3u8_formats(
|
try:
|
||||||
f'{self._USHER_BASE}/{path}/{video_id}.m3u8', video_id, 'mp4', query={
|
formats = self._extract_m3u8_formats(
|
||||||
'allow_source': 'true',
|
f'{self._USHER_BASE}/{path}/{video_id}.m3u8', video_id, 'mp4', query={
|
||||||
'allow_audio_only': 'true',
|
'allow_source': 'true',
|
||||||
'allow_spectre': 'true',
|
'allow_audio_only': 'true',
|
||||||
'p': random.randint(1000000, 10000000),
|
'allow_spectre': 'true',
|
||||||
'platform': 'web',
|
'p': random.randint(1000000, 10000000),
|
||||||
'player': 'twitchweb',
|
'platform': 'web',
|
||||||
'supported_codecs': 'av1,h265,h264',
|
'player': 'twitchweb',
|
||||||
'playlist_include_framerate': 'true',
|
'supported_codecs': 'av1,h265,h264',
|
||||||
'sig': signature,
|
'playlist_include_framerate': 'true',
|
||||||
'token': token,
|
'sig': signature,
|
||||||
})
|
'token': token,
|
||||||
|
})
|
||||||
|
except ExtractorError as e:
|
||||||
|
if (
|
||||||
|
not isinstance(e.cause, HTTPError)
|
||||||
|
or e.cause.status != 403
|
||||||
|
or e.cause.response.get_header('content-type') != 'application/json'
|
||||||
|
):
|
||||||
|
raise
|
||||||
|
|
||||||
|
error_info = traverse_obj(e.cause.response.read(), ({json.loads}, 0, {dict})) or {}
|
||||||
|
if error_info.get('error_code') in ('vod_manifest_restricted', 'unauthorized_entitlements'):
|
||||||
|
common_msg = 'access to this subscriber-only content'
|
||||||
|
if self._get_cookies('https://gql.twitch.tv').get('auth-token'):
|
||||||
|
raise ExtractorError(f'Your account does not have {common_msg}', expected=True)
|
||||||
|
self.raise_login_required(f'You must be logged into an account that has {common_msg}')
|
||||||
|
|
||||||
|
if error_msg := join_nonempty('error_code', 'error', from_dict=error_info, delim=': '):
|
||||||
|
raise ExtractorError(error_msg, expected=True)
|
||||||
|
raise
|
||||||
|
|
||||||
for fmt in formats:
|
for fmt in formats:
|
||||||
if fmt.get('vcodec') and fmt['vcodec'].startswith('av01'):
|
if fmt.get('vcodec') and fmt['vcodec'].startswith('av01'):
|
||||||
# mpegts does not yet have proper support for av1
|
# mpegts does not yet have proper support for av1
|
||||||
|
@ -3978,7 +3978,9 @@ def get_lang_code(track):
|
|||||||
def process_language(container, base_url, lang_code, sub_name, client_name, query):
|
def process_language(container, base_url, lang_code, sub_name, client_name, query):
|
||||||
lang_subs = container.setdefault(lang_code, [])
|
lang_subs = container.setdefault(lang_code, [])
|
||||||
for fmt in self._SUBTITLE_FORMATS:
|
for fmt in self._SUBTITLE_FORMATS:
|
||||||
query = {**query, 'fmt': fmt}
|
# xosf=1 results in undesirable text position data for vtt, json3 & srv* subtitles
|
||||||
|
# See: https://github.com/yt-dlp/yt-dlp/issues/13654
|
||||||
|
query = {**query, 'fmt': fmt, 'xosf': []}
|
||||||
lang_subs.append({
|
lang_subs.append({
|
||||||
'ext': fmt,
|
'ext': fmt,
|
||||||
'url': urljoin('https://www.youtube.com', update_url_query(base_url, query)),
|
'url': urljoin('https://www.youtube.com', update_url_query(base_url, query)),
|
||||||
|
Loading…
Reference in New Issue
Block a user