Merge remote-tracking branch 'upstream/master'
Some checks failed
Build and release container directly from master / release (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.12.1, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.13.2, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.14.0, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.15.0, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (nightly, false) (push) Has been cancelled
Invidious CI / build-docker (push) Has been cancelled
Invidious CI / build-docker-arm64 (push) Has been cancelled
Invidious CI / lint (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled

This commit is contained in:
Fijxu
2025-01-25 11:51:05 -03:00
41 changed files with 170 additions and 214 deletions

View File

@@ -326,17 +326,9 @@ module Invidious::Routes::Account
end
end
if env.params.query["action_revoke_token"]?
action = "action_revoke_token"
else
return env.redirect referer
end
session = env.params.query["session"]?
session ||= ""
case action
when .starts_with? "action_revoke_token"
case action = env.params.query["action"]?
when "revoke_token"
session = env.params.query["session"]
Invidious::Database::SessionIDs.delete(sid: session, email: user.email)
else
return error_json(400, "Unsupported action #{action}")

View File

@@ -75,17 +75,23 @@ module Invidious::Routes::API::Manifest
# OTF streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415)
next if !(fmt.has_key?("indexRange") && fmt.has_key?("initRange"))
audio_track = fmt["audioTrack"]?.try &.as_h? || {} of String => JSON::Any
lang = audio_track["id"]?.try &.as_s.split('.')[0] || "und"
is_default = audio_track.has_key?("audioIsDefault") ? audio_track["audioIsDefault"].as_bool : i == 0
displayname = audio_track["displayName"]?.try &.as_s || "Unknown"
bitrate = fmt["bitrate"]
# Different representations of the same audio should be groupped into one AdaptationSet.
# However, most players don't support auto quality switching, so we have to trick them
# into providing a quality selector.
# See https://github.com/iv-org/invidious/issues/3074 for more details.
xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true, label: fmt["bitrate"].to_s + "k") do
xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true, label: "#{displayname} [#{bitrate}k]", lang: lang) do
codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"')
bandwidth = fmt["bitrate"].as_i
itag = fmt["itag"].as_i
url = fmt["url"].as_s
xml.element("Role", schemeIdUri: "urn:mpeg:dash:role:2011", value: i == 0 ? "main" : "alternate")
xml.element("Role", schemeIdUri: "urn:mpeg:dash:role:2011", value: is_default ? "main" : "alternate")
xml.element("Representation", id: fmt["itag"], codecs: codecs, bandwidth: bandwidth) do
xml.element("AudioChannelConfiguration", schemeIdUri: "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
@@ -182,8 +188,9 @@ module Invidious::Routes::API::Manifest
manifest = response.body
if local
manifest = manifest.gsub(/^https:\/\/\w+---.{11}\.c\.youtube\.com[^\n]*/m) do |match|
path = URI.parse(match).path
manifest = manifest.gsub(/https:\/\/[^\n"]*/m) do |match|
uri = URI.parse(match)
path = uri.path
path = path.lchop("/videoplayback/")
path = path.rchop("/")
@@ -212,7 +219,7 @@ module Invidious::Routes::API::Manifest
raw_params["fvip"] = fvip["fvip"]
end
raw_params["local"] = "true"
raw_params["host"] = uri.host.not_nil!
proxy = Invidious::HttpServer::Utils.get_external_proxy

View File

@@ -42,6 +42,9 @@ module Invidious::Routes::API::V1::Misc
format = env.params.query["format"]?
format ||= "json"
listen_param = env.params.query["listen"]?
listen = (listen_param == "true" || listen_param == "1")
if plid.starts_with? "RD"
return env.redirect "/api/v1/mixes/#{plid}"
end
@@ -85,7 +88,7 @@ module Invidious::Routes::API::V1::Misc
end
if format == "html"
playlist_html = template_playlist(json_response)
playlist_html = template_playlist(json_response, listen)
index, next_video = json_response["videos"].as_a.skip(1 + lookback).select { |video| !video["author"].as_s.empty? }[0]?.try { |v| {v["index"], v["videoId"]} } || {nil, nil}
response = {
@@ -111,6 +114,9 @@ module Invidious::Routes::API::V1::Misc
format = env.params.query["format"]?
format ||= "json"
listen_param = env.params.query["listen"]?
listen = (listen_param == "true" || listen_param == "1")
begin
mix = fetch_mix(rdid, continuation, locale: locale)
@@ -141,9 +147,7 @@ module Invidious::Routes::API::V1::Misc
json.field "authorUrl", "/channel/#{video.ucid}"
json.field "videoThumbnails" do
json.array do
Invidious::JSONify::APIv1.thumbnails(json, video.id)
end
Invidious::JSONify::APIv1.thumbnails(json, video.id)
end
json.field "index", video.index
@@ -157,7 +161,7 @@ module Invidious::Routes::API::V1::Misc
if format == "html"
response = JSON.parse(response)
playlist_html = template_mix(response)
playlist_html = template_mix(response, listen)
next_video = response["videos"].as_a.select { |video| !video["author"].as_s.empty? }[0]?.try &.["videoId"]
response = {

View File

@@ -194,6 +194,7 @@ module Invidious::Routes::Feeds
length_seconds: 0,
premiere_timestamp: nil,
author_verified: false,
author_thumbnail: nil,
badges: VideoBadges::None,
})
end

View File

@@ -304,23 +304,6 @@ module Invidious::Routes::Playlists
end
end
if env.params.query["action_create_playlist"]?
action = "action_create_playlist"
elsif env.params.query["action_delete_playlist"]?
action = "action_delete_playlist"
elsif env.params.query["action_edit_playlist"]?
action = "action_edit_playlist"
elsif env.params.query["action_add_video"]?
action = "action_add_video"
video_id = env.params.query["video_id"]
elsif env.params.query["action_remove_video"]?
action = "action_remove_video"
elsif env.params.query["action_move_video_before"]?
action = "action_move_video_before"
else
return env.redirect referer
end
begin
playlist_id = env.params.query["playlist_id"]
playlist = get_playlist(playlist_id).as(InvidiousPlaylist)
@@ -335,12 +318,8 @@ module Invidious::Routes::Playlists
end
end
email = user.email
case action
when "action_edit_playlist"
# TODO: Playlist stub
when "action_add_video"
case action = env.params.query["action"]?
when "add_video"
if playlist.index.size >= CONFIG.playlist_length_limit
if redirect
return error_template(400, "Playlist cannot have more than #{CONFIG.playlist_length_limit} videos")
@@ -377,12 +356,14 @@ module Invidious::Routes::Playlists
Invidious::Database::PlaylistVideos.insert(playlist_video)
Invidious::Database::Playlists.update_video_added(playlist_id, playlist_video.index)
when "action_remove_video"
when "remove_video"
index = env.params.query["set_video_id"]
Invidious::Database::PlaylistVideos.delete(index)
Invidious::Database::Playlists.update_video_removed(playlist_id, index)
when "action_move_video_before"
when "move_video_before"
# TODO: Playlist stub
when nil
return error_json(400, "Missing action")
else
return error_json(400, "Unsupported action #{action}")
end

View File

@@ -32,24 +32,16 @@ module Invidious::Routes::Subscriptions
end
end
if env.params.query["action_create_subscription_to_channel"]?.try &.to_i?.try &.== 1
action = "action_create_subscription_to_channel"
elsif env.params.query["action_remove_subscriptions"]?.try &.to_i?.try &.== 1
action = "action_remove_subscriptions"
else
return env.redirect referer
end
channel_id = env.params.query["c"]?
channel_id ||= ""
case action
when "action_create_subscription_to_channel"
case action = env.params.query["action"]?
when "create_subscription_to_channel"
if !user.subscriptions.includes? channel_id
get_channel(channel_id)
Invidious::Database::Users.subscribe_channel(user, channel_id)
end
when "action_remove_subscriptions"
when "remove_subscriptions"
Invidious::Database::Users.unsubscribe_channel(user, channel_id)
else
return error_json(400, "Unsupported action #{action}")

View File

@@ -169,10 +169,13 @@ module Invidious::Routes::VideoPlayback
env.response.headers["Access-Control-Allow-Origin"] = "*"
if location = resp.headers["Location"]?
location = URI.parse(location)
location = "#{location.request_target}&host=#{location.host}#{region ? "&region=#{region}" : ""}"
url = Invidious::HttpServer::Utils.proxy_video_url(location, region: region)
env.redirect location
if title = query_params["title"]?
url = "#{url}&title=#{URI.encode_www_form(title)}"
end
env.redirect url
break
end

View File

@@ -131,9 +131,6 @@ module Invidious::Routes::Watch
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) }
end
# Always proxy DASH streams, otherwise youtube CORS headers will prevent playback
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(HttpServer::Utils.proxy_video_url(fmt["url"].as_s)) }
video_streams = video.video_streams
audio_streams = video.audio_streams
@@ -263,18 +260,10 @@ module Invidious::Routes::Watch
end
end
if env.params.query["action_mark_watched"]?
action = "action_mark_watched"
elsif env.params.query["action_mark_unwatched"]?
action = "action_mark_unwatched"
else
return env.redirect referer
end
case action
when "action_mark_watched"
case action = env.params.query["action"]?
when "mark_watched"
Invidious::Database::Users.mark_watched(user, id)
when "action_mark_unwatched"
when "mark_unwatched"
Invidious::Database::Users.mark_unwatched(user, id)
else
return error_json(400, "Unsupported action #{action}")