diff --git a/src/helpers.cr b/src/helpers.cr index b260ec9b..4ac08f9e 100644 --- a/src/helpers.cr +++ b/src/helpers.cr @@ -175,14 +175,39 @@ def search(query, client) end end -def decrypt_signature(a) - a = a.split("") - a.delete_at(0..2) - a = a.reverse +def swap(a, b) c = a[0] - a[0] = a[49 % a.size] - a[49] = c - return a.join("") + a[0] = a[b % a.size] + a[b % a.size] = c + return a +end + +def decrypt_signature(a, base) + if a && base + a = a.split("") + + if base == "vflG9lb96" + a = swap(a, 26) + a.reverse! + a = swap(a, 8) + a = swap(a, 61) + elsif base == "vflxuxnEY" + a.delete_at(0..2) + a.reverse! + c = a[0] + a[0] = a[49 % a.size] + a[49] = c + elsif base == "vflAXQwEj" + a = swap(a, 26) + a.reverse! + a = swap(a, 8) + a = swap(a, 61) + else + raise "Could not decrypt signature for player #{base}" + end + + return a.join("") + end end def rank_videos(db, n) diff --git a/src/invidious.cr b/src/invidious.cr index b7bbc5af..2a5ff4e0 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -168,12 +168,32 @@ get "/watch" do |env| fmt_stream << HTTP::Params.parse(string) end - if fmt_stream[0]? - if fmt_stream[0]["s"]? - fmt_stream.each do |fmt| - fmt["url"] = "#{fmt["url"]}&signature=#{decrypt_signature(fmt["s"])}" - end + base = nil + if fmt_stream[0]? && fmt_stream[0]["s"]? + base = video.html.xpath_node(%q(//script[@name="player/base"])) + + if !base + base = video.html.xpath_node(%q(//script[@name="player_ias/base"])) end + + if base + base = base["src"] + base = base.split("/")[3].split("-")[1] + end + end + + begin + fmt_stream.each do |fmt| + if fmt["s"]? && !base + File.write("info/#{id}.html", video.html) + raise "Could not find signature for #{video.id}" + end + + fmt["url"] = "#{fmt["url"]}&signature=#{decrypt_signature(fmt["s"]?, base)}" + end + rescue ex + error_message = ex + next templated "error" end # We want lowest quality first @@ -186,12 +206,8 @@ get "/watch" do |env| end end - if adaptive_fmts[0]? - if adaptive_fmts[0]["s"]? adaptive_fmts.each do |fmt| - fmt["url"] = "#{fmt["url"]}&signature=#{decrypt_signature(fmt["s"])}" - end - end + fmt["url"] = "#{fmt["url"]}&signature=#{decrypt_signature(fmt["s"]?, base)}" end rvs = [] of Hash(String, String) @@ -209,6 +225,7 @@ get "/watch" do |env| rating = video.info["avg_rating"].to_f64 engagement = ((video.dislikes.to_f + video.likes.to_f)/video.views * 100) + if video.likes > 0 || video.dislikes > 0 calculated_rating = (video.likes.to_f/(video.likes.to_f + video.dislikes.to_f) * 4 + 1) else