summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr22
-rw-r--r--src/invidious/database/users.cr2
-rw-r--r--src/invidious/exceptions.cr6
-rw-r--r--src/invidious/helpers/errors.cr15
-rw-r--r--src/invidious/routes/api/v1/videos.cr6
-rw-r--r--src/invidious/routes/video_playback.cr10
-rw-r--r--src/invidious/videos.cr44
-rw-r--r--src/invidious/views/embed.ecr2
8 files changed, 77 insertions, 30 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 06ce3ead..d4878759 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -113,16 +113,18 @@ LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level)
# Check table integrity
Invidious::Database.check_integrity(CONFIG)
-# Resolve player dependencies. This is done at compile time.
-#
-# Running the script by itself would show some colorful feedback while this doesn't.
-# Perhaps we should just move the script to runtime in order to get that feedback?
-
-{% puts "\nChecking player dependencies...\n" %}
-{% if flag?(:minified_player_dependencies) %}
- {% puts run("../scripts/fetch-player-dependencies.cr", "--minified").stringify %}
-{% else %}
- {% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
+{% if !flag?(:skip_videojs_download) %}
+ # Resolve player dependencies. This is done at compile time.
+ #
+ # Running the script by itself would show some colorful feedback while this doesn't.
+ # Perhaps we should just move the script to runtime in order to get that feedback?
+
+ {% puts "\nChecking player dependencies...\n" %}
+ {% if flag?(:minified_player_dependencies) %}
+ {% puts run("../scripts/fetch-player-dependencies.cr", "--minified").stringify %}
+ {% else %}
+ {% puts run("../scripts/fetch-player-dependencies.cr").stringify %}
+ {% end %}
{% end %}
# Start jobs
diff --git a/src/invidious/database/users.cr b/src/invidious/database/users.cr
index 26be4270..f62b43ea 100644
--- a/src/invidious/database/users.cr
+++ b/src/invidious/database/users.cr
@@ -171,7 +171,7 @@ module Invidious::Database::Users
WHERE email = $2
SQL
- PG_DB.exec(request, user.email, pass)
+ PG_DB.exec(request, pass, user.email)
end
# -------------------
diff --git a/src/invidious/exceptions.cr b/src/invidious/exceptions.cr
index 391a574d..490d98cd 100644
--- a/src/invidious/exceptions.cr
+++ b/src/invidious/exceptions.cr
@@ -1,8 +1,12 @@
# Exception used to hold the name of the missing item
# Should be used in all parsing functions
-class BrokenTubeException < InfoException
+class BrokenTubeException < Exception
getter element : String
def initialize(@element)
end
+
+ def message
+ return "Missing JSON element \"#{@element}\""
+ end
end
diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr
index 3acbac84..6155e561 100644
--- a/src/invidious/helpers/errors.cr
+++ b/src/invidious/helpers/errors.cr
@@ -38,12 +38,15 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce
issue_title = "#{exception.message} (#{exception.class})"
- issue_template = %(Title: `#{issue_title}`)
- issue_template += %(\nDate: `#{Time::Format::ISO_8601_DATE_TIME.format(Time.utc)}`)
- issue_template += %(\nRoute: `#{env.request.resource}`)
- issue_template += %(\nVersion: `#{SOFTWARE["version"]} @ #{SOFTWARE["branch"]}`)
- # issue_template += github_details("Preferences", env.get("preferences").as(Preferences).to_pretty_json)
- issue_template += github_details("Backtrace", exception.inspect_with_backtrace)
+ issue_template = <<-TEXT
+ Title: `#{HTML.escape(issue_title)}`
+ Date: `#{Time::Format::ISO_8601_DATE_TIME.format(Time.utc)}`
+ Route: `#{HTML.escape(env.request.resource)}`
+ Version: `#{SOFTWARE["version"]} @ #{SOFTWARE["branch"]}`
+
+ TEXT
+
+ issue_template += github_details("Backtrace", HTML.escape(exception.inspect_with_backtrace))
# URLs for the error message below
url_faq = "https://github.com/iv-org/documentation/blob/master/FAQ.md"
diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr
index 86eb26ee..2b23d2ad 100644
--- a/src/invidious/routes/api/v1/videos.cr
+++ b/src/invidious/routes/api/v1/videos.cr
@@ -130,7 +130,13 @@ module Invidious::Routes::API::V1::Videos
end
end
else
+ # Some captions have "align:[start/end]" and "position:[num]%"
+ # attributes. Those are causing issues with VideoJS, which is unable
+ # to properly align the captions on the video, so we remove them.
+ #
+ # See: https://github.com/iv-org/invidious/issues/2391
webvtt = YT_POOL.client &.get("#{url}&format=vtt").body
+ .gsub(/([0-9:.]+ --> [0-9:.]+).+/, "\\1")
end
if title = env.params.query["title"]?
diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr
index f6340c57..6ac1e780 100644
--- a/src/invidious/routes/video_playback.cr
+++ b/src/invidious/routes/video_playback.cr
@@ -14,12 +14,18 @@ module Invidious::Routes::VideoPlayback
end
if query_params["host"]? && !query_params["host"].empty?
- host = "https://#{query_params["host"]}"
+ host = query_params["host"]
query_params.delete("host")
else
- host = "https://r#{fvip}---#{mns.pop}.googlevideo.com"
+ host = "r#{fvip}---#{mns.pop}.googlevideo.com"
end
+ # Sanity check, to avoid being used as an open proxy
+ if !host.matches?(/[\w-]+.googlevideo.com/)
+ return error_template(400, "Invalid \"host\" parameter.")
+ end
+
+ host = "https://#{host}"
url = "/videoplayback?#{query_params}"
headers = HTTP::Headers.new
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index 446e8e03..81fce5b8 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -2,6 +2,8 @@ CAPTION_LANGUAGES = {
"",
"English",
"English (auto-generated)",
+ "English (United Kingdom)",
+ "English (United States)",
"Afrikaans",
"Albanian",
"Amharic",
@@ -14,23 +16,31 @@ CAPTION_LANGUAGES = {
"Bosnian",
"Bulgarian",
"Burmese",
+ "Cantonese (Hong Kong)",
"Catalan",
"Cebuano",
+ "Chinese",
+ "Chinese (China)",
+ "Chinese (Hong Kong)",
"Chinese (Simplified)",
+ "Chinese (Taiwan)",
"Chinese (Traditional)",
"Corsican",
"Croatian",
"Czech",
"Danish",
"Dutch",
+ "Dutch (auto-generated)",
"Esperanto",
"Estonian",
"Filipino",
"Finnish",
"French",
+ "French (auto-generated)",
"Galician",
"Georgian",
"German",
+ "German (auto-generated)",
"Greek",
"Gujarati",
"Haitian Creole",
@@ -43,14 +53,19 @@ CAPTION_LANGUAGES = {
"Icelandic",
"Igbo",
"Indonesian",
+ "Indonesian (auto-generated)",
+ "Interlingue",
"Irish",
"Italian",
+ "Italian (auto-generated)",
"Japanese",
+ "Japanese (auto-generated)",
"Javanese",
"Kannada",
"Kazakh",
"Khmer",
"Korean",
+ "Korean (auto-generated)",
"Kurdish",
"Kyrgyz",
"Lao",
@@ -73,9 +88,12 @@ CAPTION_LANGUAGES = {
"Persian",
"Polish",
"Portuguese",
+ "Portuguese (auto-generated)",
+ "Portuguese (Brazil)",
"Punjabi",
"Romanian",
"Russian",
+ "Russian (auto-generated)",
"Samoan",
"Scottish Gaelic",
"Serbian",
@@ -87,7 +105,10 @@ CAPTION_LANGUAGES = {
"Somali",
"Southern Sotho",
"Spanish",
+ "Spanish (auto-generated)",
"Spanish (Latin America)",
+ "Spanish (Mexico)",
+ "Spanish (Spain)",
"Sundanese",
"Swahili",
"Swedish",
@@ -96,10 +117,12 @@ CAPTION_LANGUAGES = {
"Telugu",
"Thai",
"Turkish",
+ "Turkish (auto-generated)",
"Ukrainian",
"Urdu",
"Uzbek",
"Vietnamese",
+ "Vietnamese (auto-generated)",
"Welsh",
"Western Frisian",
"Xhosa",
@@ -858,11 +881,13 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_
player_response = YoutubeAPI.player(video_id: video_id, params: "", client_config: client_config)
- if player_response["playabilityStatus"]?.try &.["status"]?.try &.as_s != "OK"
- reason = player_response["playabilityStatus"]["errorScreen"]?.try &.["playerErrorMessageRenderer"]?.try &.["subreason"]?.try { |s|
- s["simpleText"]?.try &.as_s || s["runs"].as_a.map { |r| r["text"] }.join("")
- } || player_response["playabilityStatus"]["reason"].as_s
+ if player_response.dig?("playabilityStatus", "status").try &.as_s != "OK"
+ subreason = player_response.dig?("playabilityStatus", "errorScreen", "playerErrorMessageRenderer", "subreason")
+ reason = subreason.try &.[]?("simpleText").try &.as_s
+ reason ||= subreason.try &.[]("runs").as_a.map(&.[]("text")).join("")
+ reason ||= player_response.dig("playabilityStatus", "reason").as_s
params["reason"] = JSON::Any.new(reason)
+ return params
end
params["shortDescription"] = player_response.dig?("videoDetails", "shortDescription") || JSON::Any.new(nil)
@@ -905,11 +930,8 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_
raise BrokenTubeException.new("twoColumnWatchNextResults") if !main_results
primary_results = main_results.dig?("results", "results", "contents")
- secondary_results = main_results
- .dig?("secondaryResults", "secondaryResults", "results")
raise BrokenTubeException.new("results") if !primary_results
- raise BrokenTubeException.new("secondaryResults") if !secondary_results
video_primary_renderer = primary_results
.as_a.find(&.["videoPrimaryInfoRenderer"]?)
@@ -929,7 +951,9 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_
related = [] of JSON::Any
# Parse "compactVideoRenderer" items (under secondary results)
- secondary_results.as_a.each do |element|
+ secondary_results = main_results
+ .dig?("secondaryResults", "secondaryResults", "results")
+ secondary_results.try &.as_a.each do |element|
if item = element["compactVideoRenderer"]?
related_video = parse_related_video(item)
related << JSON::Any.new(related_video) if related_video
@@ -1096,7 +1120,9 @@ def fetch_video(id, region)
info = embed_info if !embed_info["reason"]?
end
- raise InfoException.new(info["reason"]?.try &.as_s || "") if !info["videoDetails"]?
+ if reason = info["reason"]?
+ raise InfoException.new(reason.as_s || "")
+ end
video = Video.new({
id: id,
diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr
index cd0fd0d5..27a8e266 100644
--- a/src/invidious/views/embed.ecr
+++ b/src/invidious/views/embed.ecr
@@ -7,7 +7,7 @@
<meta name="thumbnail" content="<%= thumbnail %>">
<%= rendered "components/player_sources" %>
<link rel="stylesheet" href="/videojs/videojs-overlay/videojs-overlay.css?v=<%= ASSET_COMMIT %>">
- <script src="videojs/videojs-overlay/videojs-overlay.js?v=<%= ASSET_COMMIT %>"></script>
+ <script src="/videojs/videojs-overlay/videojs-overlay.js?v=<%= ASSET_COMMIT %>"></script>
<link rel="stylesheet" href="/css/default.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/embed.css?v=<%= ASSET_COMMIT %>">
<title><%= HTML.escape(video.title) %> - Invidious</title>