mirror of
https://github.com/iv-org/invidious.git
synced 2025-12-03 20:38:29 -06:00
Remove DECRYPT_FUNCTION and shrink player function
This commit is contained in:
parent
e649b8105a
commit
0df8b38123
@ -170,10 +170,6 @@ Invidious::Database.check_integrity(CONFIG)
|
||||
{% puts "\nDone checking player dependencies, now compiling Invidious...\n" %}
|
||||
{% end %}
|
||||
|
||||
# Misc
|
||||
|
||||
DECRYPT_FUNCTION = nil
|
||||
|
||||
# Start jobs
|
||||
|
||||
if CONFIG.channel_threads > 0
|
||||
|
||||
@ -326,6 +326,10 @@ end
|
||||
def fetch_video(id, region)
|
||||
info = extract_video_info(video_id: id)
|
||||
|
||||
if info.nil?
|
||||
raise InfoException.new("Invidious companion is not available. Video playback cannot continue.")
|
||||
end
|
||||
|
||||
if reason = info["reason"]?
|
||||
if reason == "Video unavailable"
|
||||
raise NotFoundException.new(reason.as_s || "")
|
||||
|
||||
@ -53,11 +53,12 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)?
|
||||
end
|
||||
|
||||
def extract_video_info(video_id : String)
|
||||
# Init client config for the API
|
||||
client_config = YoutubeAPI::ClientConfig.new
|
||||
|
||||
# Fetch data from the player endpoint
|
||||
player_response = YoutubeAPI.player(video_id: video_id, params: "2AMB", client_config: client_config)
|
||||
player_response = YoutubeAPI.player(video_id: video_id)
|
||||
|
||||
if player_response.nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
playability_status = player_response.dig?("playabilityStatus", "status").try &.as_s
|
||||
|
||||
@ -105,37 +106,6 @@ def extract_video_info(video_id : String)
|
||||
params = parse_video_info(video_id, player_response)
|
||||
params["reason"] = JSON::Any.new(reason) if reason
|
||||
|
||||
if !CONFIG.invidious_companion.present?
|
||||
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::TvSimply, YoutubeAPI::ClientType::WebMobile}
|
||||
|
||||
players_fallback.each do |player_fallback|
|
||||
client_config.client_type = player_fallback
|
||||
|
||||
next if !(player_fallback_response = try_fetch_streaming_data(video_id, client_config))
|
||||
|
||||
adaptive_formats = player_fallback_response.dig?("streamingData", "adaptiveFormats")
|
||||
if adaptive_formats && (adaptive_formats.dig?(0, "url") || adaptive_formats.dig?(0, "signatureCipher"))
|
||||
streaming_data = player_response["streamingData"].as_h
|
||||
streaming_data["adaptiveFormats"] = adaptive_formats
|
||||
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|
|
||||
params[f] = player_response[f] if player_response[f]?
|
||||
end
|
||||
@ -163,7 +133,7 @@ end
|
||||
|
||||
def try_fetch_streaming_data(id : String, client_config : YoutubeAPI::ClientConfig) : Hash(String, JSON::Any)?
|
||||
LOGGER.debug("try_fetch_streaming_data: [#{id}] Using #{client_config.client_type} client.")
|
||||
response = YoutubeAPI.player(video_id: id, params: "2AMB", client_config: client_config)
|
||||
response = YoutubeAPI.player(video_id: id)
|
||||
|
||||
playability_status = response["playabilityStatus"]["status"]
|
||||
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_status}.")
|
||||
@ -480,17 +450,11 @@ private def convert_url(fmt)
|
||||
params = url.query_params
|
||||
|
||||
LOGGER.debug("convert_url: Decoding '#{cfr}'")
|
||||
|
||||
unsig = DECRYPT_FUNCTION.try &.decrypt_signature(cfr["s"])
|
||||
params[sp] = unsig if unsig
|
||||
else
|
||||
url = URI.parse(fmt["url"].as_s)
|
||||
params = url.query_params
|
||||
end
|
||||
|
||||
n = DECRYPT_FUNCTION.try &.decrypt_nsig(params["n"])
|
||||
params["n"] = n if n
|
||||
|
||||
url.query_params = params
|
||||
LOGGER.trace("convert_url: new url is '#{url}'")
|
||||
|
||||
|
||||
@ -199,10 +199,6 @@ module YoutubeAPI
|
||||
# conf_1 = ClientConfig.new(region: "NO")
|
||||
# YoutubeAPI::search("Kollektivet", params: "", client_config: conf_1)
|
||||
#
|
||||
# # Use the Android client to request video streams URLs
|
||||
# conf_2 = ClientConfig.new(client_type: ClientType::Android)
|
||||
# YoutubeAPI::player(video_id: "dQw4w9WgXcQ", client_config: conf_2)
|
||||
#
|
||||
#
|
||||
struct ClientConfig
|
||||
# Type of client to emulate.
|
||||
@ -451,58 +447,23 @@ module YoutubeAPI
|
||||
end
|
||||
|
||||
####################################################################
|
||||
# player(video_id, params, client_config?)
|
||||
# player(video_id)
|
||||
#
|
||||
# Requests the youtubei/v1/player endpoint with the required headers
|
||||
# and POST data in order to get a JSON reply.
|
||||
# Requests the youtubei/v1/player Invidious Companion endpoint with
|
||||
# the requested video ID.
|
||||
#
|
||||
# The requested data is a video ID (`v=` parameter), with some
|
||||
# additional parameters, formatted as a base64 string.
|
||||
# The requested data is a video ID (`v=` parameter).
|
||||
#
|
||||
# An optional ClientConfig parameter can be passed, too (see
|
||||
# `struct ClientConfig` above for more details).
|
||||
#
|
||||
def player(
|
||||
video_id : String,
|
||||
*, # Force the following parameters to be passed by name
|
||||
params : String,
|
||||
client_config : ClientConfig | Nil = nil,
|
||||
)
|
||||
# Playback context, separate because it can be different between clients
|
||||
playback_ctx = {
|
||||
"html5Preference" => "HTML5_PREF_WANTS",
|
||||
"referer" => "https://www.youtube.com/watch?v=#{video_id}",
|
||||
} of String => String | Int64
|
||||
|
||||
if {"WEB", "TVHTML5"}.any? { |s| client_config.name.starts_with? s }
|
||||
if sts = DECRYPT_FUNCTION.try &.get_sts
|
||||
playback_ctx["signatureTimestamp"] = sts.to_i64
|
||||
end
|
||||
end
|
||||
|
||||
# JSON Request data, required by the API
|
||||
def player(video_id : String)
|
||||
# JSON Request data, required by Invidious Companion
|
||||
data = {
|
||||
"contentCheckOk" => true,
|
||||
"videoId" => video_id,
|
||||
"context" => self.make_context(client_config, video_id),
|
||||
"racyCheckOk" => true,
|
||||
"user" => {
|
||||
"lockedSafetyMode" => false,
|
||||
},
|
||||
"playbackContext" => {
|
||||
"contentPlaybackContext" => playback_ctx,
|
||||
},
|
||||
}
|
||||
|
||||
# Append the additional parameters if those were provided
|
||||
if params != ""
|
||||
data["params"] = params
|
||||
end
|
||||
|
||||
if CONFIG.invidious_companion.present?
|
||||
return self._post_invidious_companion("/youtubei/v1/player", data)
|
||||
else
|
||||
return self._post_json("/youtubei/v1/player", data, client_config)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user