Fixed problem with new youtube player, leading to "Unable to extract video data".

This commit is contained in:
Peter Oettig 2020-10-30 23:24:55 +01:00
parent 4932ba4aec
commit 59c5fa91c1
1 changed files with 70 additions and 53 deletions

View File

@ -1390,6 +1390,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
# https://github.com/ytdl-org/youtube-dl/pull/7599) # https://github.com/ytdl-org/youtube-dl/pull/7599)
r';ytplayer\.config\s*=\s*({.+?});ytplayer', r';ytplayer\.config\s*=\s*({.+?});ytplayer',
r';ytplayer\.config\s*=\s*({.+?});', r';ytplayer\.config\s*=\s*({.+?});',
r'ytInitialPlayerResponse\s*=\s*({.+?});var meta'
) )
config = self._search_regex( config = self._search_regex(
patterns, webpage, 'ytplayer.config', default=None) patterns, webpage, 'ytplayer.config', default=None)
@ -1416,10 +1417,11 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
self._downloader.report_warning(err_msg) self._downloader.report_warning(err_msg)
return {} return {}
try: try:
if "args" in player_config and "ttsurl" in player_config["args"]:
args = player_config['args'] args = player_config['args']
caption_url = args.get('ttsurl') caption_url = args['ttsurl']
if caption_url:
timestamp = args['timestamp'] timestamp = args['timestamp']
# We get the available subtitles # We get the available subtitles
list_params = compat_urllib_parse_urlencode({ list_params = compat_urllib_parse_urlencode({
'type': 'list', 'type': 'list',
@ -1475,11 +1477,17 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
return captions return captions
# New captions format as of 22.06.2017 # New captions format as of 22.06.2017
player_response = args.get('player_response') if "args" in player_config:
if player_response and isinstance(player_response, compat_str): player_response = player_config["args"].get('player_response')
else:
# New player system (ytInitialPlayerResponse) as of October 2020
player_response = player_config
if player_response:
if isinstance(player_response, compat_str):
player_response = self._parse_json( player_response = self._parse_json(
player_response, video_id, fatal=False) player_response, video_id, fatal=False)
if player_response:
renderer = player_response['captions']['playerCaptionsTracklistRenderer'] renderer = player_response['captions']['playerCaptionsTracklistRenderer']
caption_tracks = renderer['captionTracks'] caption_tracks = renderer['captionTracks']
for caption_track in caption_tracks: for caption_track in caption_tracks:
@ -1496,6 +1504,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
self._downloader.report_warning("Couldn't find automatic captions for %s" % video_id) self._downloader.report_warning("Couldn't find automatic captions for %s" % video_id)
return {} return {}
if "args" in player_config:
args = player_config["args"]
# Some videos don't provide ttsurl but rather caption_tracks and # Some videos don't provide ttsurl but rather caption_tracks and
# caption_translation_languages (e.g. 20LmZk1hakA) # caption_translation_languages (e.g. 20LmZk1hakA)
# Does not used anymore as of 22.06.2017 # Does not used anymore as of 22.06.2017
@ -1784,7 +1796,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
# Try looking directly into the video webpage # Try looking directly into the video webpage
ytplayer_config = self._get_ytplayer_config(video_id, video_webpage) ytplayer_config = self._get_ytplayer_config(video_id, video_webpage)
if ytplayer_config: if ytplayer_config:
args = ytplayer_config['args'] args = ytplayer_config.get("args")
if args is not None:
if args.get('url_encoded_fmt_stream_map') or args.get('hlsvp'): if args.get('url_encoded_fmt_stream_map') or args.get('hlsvp'):
# Convert to the same format returned by compat_parse_qs # Convert to the same format returned by compat_parse_qs
video_info = dict((k, [v]) for k, v in args.items()) video_info = dict((k, [v]) for k, v in args.items())
@ -1799,6 +1812,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
is_live = True is_live = True
if not player_response: if not player_response:
player_response = extract_player_response(args.get('player_response'), video_id) player_response = extract_player_response(args.get('player_response'), video_id)
elif not player_response:
player_response = ytplayer_config
if not video_info or self._downloader.params.get('youtube_include_dash_manifest', True): if not video_info or self._downloader.params.get('youtube_include_dash_manifest', True):
add_dash_mpd_pr(player_response) add_dash_mpd_pr(player_response)
else: else:
@ -1828,8 +1843,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
age_gate = False age_gate = False
# Try looking directly into the video webpage # Try looking directly into the video webpage
ytplayer_config = self._get_ytplayer_config(video_id, video_webpage) ytplayer_config = self._get_ytplayer_config(video_id, video_webpage)
if ytplayer_config: args = ytplayer_config.get("args")
args = ytplayer_config['args'] if args is not None:
if args.get('url_encoded_fmt_stream_map') or args.get('hlsvp'): if args.get('url_encoded_fmt_stream_map') or args.get('hlsvp'):
# Convert to the same format returned by compat_parse_qs # Convert to the same format returned by compat_parse_qs
video_info = dict((k, [v]) for k, v in args.items()) video_info = dict((k, [v]) for k, v in args.items())
@ -1844,6 +1859,8 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
is_live = True is_live = True
if not player_response: if not player_response:
player_response = extract_player_response(args.get('player_response'), video_id) player_response = extract_player_response(args.get('player_response'), video_id)
elif not player_response:
player_response = ytplayer_config
if not video_info or self._downloader.params.get('youtube_include_dash_manifest', True): if not video_info or self._downloader.params.get('youtube_include_dash_manifest', True):
add_dash_mpd_pr(player_response) add_dash_mpd_pr(player_response)