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" %}
|
{% puts "\nDone checking player dependencies, now compiling Invidious...\n" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
# Misc
|
|
||||||
|
|
||||||
DECRYPT_FUNCTION = nil
|
|
||||||
|
|
||||||
# Start jobs
|
# Start jobs
|
||||||
|
|
||||||
if CONFIG.channel_threads > 0
|
if CONFIG.channel_threads > 0
|
||||||
|
|||||||
@ -326,6 +326,10 @@ end
|
|||||||
def fetch_video(id, region)
|
def fetch_video(id, region)
|
||||||
info = extract_video_info(video_id: id)
|
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 = info["reason"]?
|
||||||
if reason == "Video unavailable"
|
if reason == "Video unavailable"
|
||||||
raise NotFoundException.new(reason.as_s || "")
|
raise NotFoundException.new(reason.as_s || "")
|
||||||
|
|||||||
@ -53,11 +53,12 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)?
|
|||||||
end
|
end
|
||||||
|
|
||||||
def extract_video_info(video_id : String)
|
def extract_video_info(video_id : String)
|
||||||
# Init client config for the API
|
|
||||||
client_config = YoutubeAPI::ClientConfig.new
|
|
||||||
|
|
||||||
# Fetch data from the player endpoint
|
# 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
|
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 = parse_video_info(video_id, player_response)
|
||||||
params["reason"] = JSON::Any.new(reason) if reason
|
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|
|
{"captions", "playabilityStatus", "playerConfig", "storyboards"}.each do |f|
|
||||||
params[f] = player_response[f] if player_response[f]?
|
params[f] = player_response[f] if player_response[f]?
|
||||||
end
|
end
|
||||||
@ -163,7 +133,7 @@ end
|
|||||||
|
|
||||||
def try_fetch_streaming_data(id : String, client_config : YoutubeAPI::ClientConfig) : Hash(String, JSON::Any)?
|
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.")
|
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"]
|
playability_status = response["playabilityStatus"]["status"]
|
||||||
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_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
|
params = url.query_params
|
||||||
|
|
||||||
LOGGER.debug("convert_url: Decoding '#{cfr}'")
|
LOGGER.debug("convert_url: Decoding '#{cfr}'")
|
||||||
|
|
||||||
unsig = DECRYPT_FUNCTION.try &.decrypt_signature(cfr["s"])
|
|
||||||
params[sp] = unsig if unsig
|
|
||||||
else
|
else
|
||||||
url = URI.parse(fmt["url"].as_s)
|
url = URI.parse(fmt["url"].as_s)
|
||||||
params = url.query_params
|
params = url.query_params
|
||||||
end
|
end
|
||||||
|
|
||||||
n = DECRYPT_FUNCTION.try &.decrypt_nsig(params["n"])
|
|
||||||
params["n"] = n if n
|
|
||||||
|
|
||||||
url.query_params = params
|
url.query_params = params
|
||||||
LOGGER.trace("convert_url: new url is '#{url}'")
|
LOGGER.trace("convert_url: new url is '#{url}'")
|
||||||
|
|
||||||
|
|||||||
@ -199,10 +199,6 @@ module YoutubeAPI
|
|||||||
# conf_1 = ClientConfig.new(region: "NO")
|
# conf_1 = ClientConfig.new(region: "NO")
|
||||||
# YoutubeAPI::search("Kollektivet", params: "", client_config: conf_1)
|
# 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
|
struct ClientConfig
|
||||||
# Type of client to emulate.
|
# Type of client to emulate.
|
||||||
@ -451,58 +447,23 @@ module YoutubeAPI
|
|||||||
end
|
end
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
# player(video_id, params, client_config?)
|
# player(video_id)
|
||||||
#
|
#
|
||||||
# Requests the youtubei/v1/player endpoint with the required headers
|
# Requests the youtubei/v1/player Invidious Companion endpoint with
|
||||||
# and POST data in order to get a JSON reply.
|
# the requested video ID.
|
||||||
#
|
#
|
||||||
# The requested data is a video ID (`v=` parameter), with some
|
# The requested data is a video ID (`v=` parameter).
|
||||||
# additional parameters, formatted as a base64 string.
|
|
||||||
#
|
#
|
||||||
# An optional ClientConfig parameter can be passed, too (see
|
def player(video_id : String)
|
||||||
# `struct ClientConfig` above for more details).
|
# JSON Request data, required by Invidious Companion
|
||||||
#
|
|
||||||
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
|
|
||||||
data = {
|
data = {
|
||||||
"contentCheckOk" => true,
|
"videoId" => video_id,
|
||||||
"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?
|
if CONFIG.invidious_companion.present?
|
||||||
return self._post_invidious_companion("/youtubei/v1/player", data)
|
return self._post_invidious_companion("/youtubei/v1/player", data)
|
||||||
else
|
else
|
||||||
return self._post_json("/youtubei/v1/player", data, client_config)
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user