diff --git a/src/invidious.cr b/src/invidious.cr index e6130f34..9be7fd85 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -237,6 +237,8 @@ get "/watch" do |env| begin video = get_video(id, PG_DB, proxies) + rescue ex : VideoRedirect + next env.redirect "/watch?v=#{ex.message}" rescue ex error_message = ex.message STDOUT << id << " : " << ex.message << "\n" @@ -337,6 +339,8 @@ get "/embed/:id" do |env| begin video = get_video(id, PG_DB, proxies) + rescue ex : VideoRedirect + next env.redirect "/embed/#{ex.message}" rescue ex error_message = ex.message next templated "error" @@ -1777,6 +1781,8 @@ get "/api/v1/captions/:id" do |env| client = make_client(YT_URL) begin video = get_video(id, PG_DB, proxies) + rescue ex : VideoRedirect + next env.redirect "/api/v1/captions/#{ex.message}" rescue ex halt env, status_code: 403 end @@ -2228,6 +2234,8 @@ get "/api/v1/videos/:id" do |env| begin video = get_video(id, PG_DB, proxies) + rescue ex : VideoRedirect + next env.redirect "/api/v1/videos/#{ex.message}" rescue ex error_message = {"error" => ex.message}.to_json halt env, status_code: 500, response: error_message @@ -3074,6 +3082,8 @@ get "/api/manifest/dash/id/:id" do |env| client = make_client(YT_URL) begin video = get_video(id, PG_DB, proxies) + rescue ex : VideoRedirect + next env.redirect "/api/manifest/dash/id/#{ex.message}" rescue ex halt env, status_code: 403 end diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 42adb3b4..9398943d 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -477,6 +477,9 @@ class CaptionName ) end +class VideoRedirect < Exception +end + def get_video(id, db, proxies = {} of String => Array({ip: String, port: Int32}), refresh = true) if db.query_one?("SELECT EXISTS (SELECT true FROM videos WHERE id = $1)", id, as: Bool) video = db.query_one("SELECT * FROM videos WHERE id = $1", id, as: Video) @@ -511,14 +514,18 @@ def get_video(id, db, proxies = {} of String => Array({ip: String, port: Int32}) end def fetch_video(id, proxies) - html_channel = Channel(XML::Node).new + html_channel = Channel(XML::Node | String).new info_channel = Channel(HTTP::Params).new spawn do client = make_client(YT_URL) html = client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&gl=US&hl=en&disable_polymer=1") - html = XML.parse_html(html.body) + if md = html.headers["location"]?.try &.match(/v=(?[a-zA-Z0-9_-]{11})/) + next html_channel.send(md["id"]) + end + + html = XML.parse_html(html.body) html_channel.send(html) end @@ -536,6 +543,11 @@ def fetch_video(id, proxies) end html = html_channel.receive + if html.as?(String) + raise VideoRedirect.new("#{html.as(String)}") + end + html = html.as(XML::Node) + info = info_channel.receive if info["reason"]? && info["reason"].includes? "your country"