summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsyeopite <70992037+syeopite@users.noreply.github.com>2025-05-28 20:18:51 +0000
committerGitHub <noreply@github.com>2025-05-28 20:18:51 +0000
commitdf8839d1f018644afecb15e144f228d811708f8f (patch)
tree8411d077a23dec61dc374130e0fd343709930a25 /src
parentb859faebf057b7dde7733cfb68b9a3b77d648133 (diff)
downloadinvidious-df8839d1f018644afecb15e144f228d811708f8f.tar.gz
invidious-df8839d1f018644afecb15e144f228d811708f8f.tar.bz2
invidious-df8839d1f018644afecb15e144f228d811708f8f.zip
Make base-Invidious video info extraction more resilient (#5312)
Try next fallback client if one raises Convert `dig` to `dig?` Optimize companionless stream retrieval
Diffstat (limited to 'src')
-rw-r--r--src/invidious/videos/parser.cr26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr
index 15bd00b6..feb58440 100644
--- a/src/invidious/videos/parser.cr
+++ b/src/invidious/videos/parser.cr
@@ -82,7 +82,7 @@ def extract_video_info(video_id : String)
"reason" => JSON::Any.new(reason),
}
end
- elsif video_id != player_response.dig("videoDetails", "videoId")
+ elsif video_id != player_response.dig?("videoDetails", "videoId")
# YouTube may return a different video player response than expected.
# See: https://github.com/TeamNewPipe/NewPipe/issues/8713
# Line to be reverted if one day we solve the video not available issue.
@@ -109,21 +109,33 @@ def extract_video_info(video_id : String)
params["reason"] = JSON::Any.new(reason) if reason
if !CONFIG.invidious_companion.present?
- if player_response["streamingData"]? && player_response.dig?("streamingData", "adaptiveFormats", 0, "url").nil?
+ if 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 = {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")
+
+ next if !(player_fallback_response = try_fetch_streaming_data(video_id, client_config))
+
+ if 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
+ rescue InfoException
+ next LOGGER.warn("Failed to fetch streams with #{player_fallback}")
end
end
+
+ # Seems like video page can still render even without playable streams.
+ # its better than nothing.
+ #
+ # # Were we able to find playable video streams?
+ # if player_response.dig?("streamingData", "adaptiveFormats", 0, "url").nil?
+ # # No :(
+ # end
end
{"captions", "playabilityStatus", "playerConfig", "storyboards"}.each do |f|
@@ -154,7 +166,7 @@ def try_fetch_streaming_data(id : String, client_config : YoutubeAPI::ClientConf
playability_status = response["playabilityStatus"]["status"]
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_status}.")
- if id != response.dig("videoDetails", "videoId")
+ if id != response.dig?("videoDetails", "videoId")
# YouTube may return a different video player response than expected.
# See: https://github.com/TeamNewPipe/NewPipe/issues/8713
raise InfoException.new(