diff --git a/CHANGELOG.md b/CHANGELOG.md index f84dc790..98b66ba4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ ## vX.Y.0 (future) +## v2.20250517.0 + +Inverse fallback for the YouTube client from TVHTML then MWEB. Fixes https://github.com/iv-org/invidious/issues/5273 + +## v2.20250504.0 + +Small release with quick workaround fix for issue #4251 (Nil assertion failed). + +PR: https://github.com/iv-org/invidious/issues/5263 + ## v2.20250314.0 ### Wrap-up diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 5ca4bdb2..b5fc1444 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -108,27 +108,20 @@ def extract_video_info(video_id : String) params = parse_video_info(video_id, player_response) params["reason"] = JSON::Any.new(reason) if reason - new_player_response = nil - - # Don't use Android test suite client if po_token is passed because po_token doesn't - # work for Android test suite client. - if reason.nil? && CONFIG.po_token.nil? - # Fetch the video streams using an Android client in order to get the - # decrypted URLs and maybe fix throttling issues (#2194). See the - # following issue for an explanation about decrypted URLs: - # https://github.com/TeamNewPipe/NewPipeExtractor/issues/562 - client_config.client_type = YoutubeAPI::ClientType::AndroidTestSuite - new_player_response = try_fetch_streaming_data(video_id, client_config) - end - - # Replace player response and reset reason - if !new_player_response.nil? - # Preserve captions & storyboard data before replacement - new_player_response["storyboards"] = player_response["storyboards"] if player_response["storyboards"]? - new_player_response["captions"] = player_response["captions"] if player_response["captions"]? - - player_response = new_player_response - params.delete("reason") + if player_response["streamingData"]? && player_response.dig?("streamingData", "adaptiveFormats", 0, "url").nil? + LOGGER.warn("Missing URLs for adaptive formats, falling back to other YT clients.") + players_fallback = [YoutubeAPI::ClientType::TvHtml5, YoutubeAPI::ClientType::WebMobile] + players_fallback.each do |player_fallback| + client_config.client_type = player_fallback + player_fallback_response = try_fetch_streaming_data(video_id, client_config) + if player_fallback_response && player_fallback_response["streamingData"]? && + player_fallback_response.dig?("streamingData", "adaptiveFormats", 0, "url") + streaming_data = player_response["streamingData"].as_h + streaming_data["adaptiveFormats"] = player_fallback_response["streamingData"]["adaptiveFormats"] + player_response["streamingData"] = JSON::Any.new(streaming_data) + break + end + end end {"captions", "playabilityStatus", "playerConfig", "storyboards"}.each do |f|