summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr77
-rw-r--r--src/invidious/views/watch.ecr6
2 files changed, 83 insertions, 0 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index f046b750..5234fe00 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -145,6 +145,7 @@ channel_threads.times do |i|
end
end
end
+
Fiber.yield
end
end
@@ -170,6 +171,7 @@ video_threads.times do |i|
end
end
end
+
Fiber.yield
end
end
@@ -349,6 +351,13 @@ get "/watch" do |env|
stream["bitrate"] = (stream["bitrate"].to_f64/1000).to_i.to_s
end
+ player_response = JSON.parse(video.info["player_response"])
+ if player_response["captions"]?
+ captions = player_response["captions"]["playerCaptionsTracklistRenderer"]["captionTracks"].as_a
+ else
+ captions = [] of JSON::Any
+ end
+
rvs = [] of Hash(String, String)
if video.info.has_key?("rvs")
video.info["rvs"].split(",").each do |rv|
@@ -396,6 +405,74 @@ get "/watch" do |env|
templated "watch"
end
+get "/captions/:id" do |env|
+ id = env.params.url["id"]
+
+ client = make_client(YT_URL)
+ begin
+ video = get_video(id, client, PG_DB)
+ rescue ex
+ error_message = ex.message
+ next templated "error"
+ end
+
+ env.response.content_type = "application/json"
+
+ player_response = JSON.parse(video.info["player_response"])
+ if !player_response["captions"]?
+ next "{}"
+ end
+
+ tracks = player_response["captions"]["playerCaptionsTracklistRenderer"]["captionTracks"].as_a
+
+ label = env.params.query["label"]?
+ track = tracks.select { |tracks| tracks["name"]["simpleText"] == label }
+
+ env.response.content_type = "text/vtt"
+ if track.empty?
+ if tracks.empty?
+ halt env, status_code: 403
+ else
+ track = tracks[0]
+ end
+ else
+ track = track[0]
+ end
+
+ track_xml = client.get(track["baseUrl"].as_s).body
+ track_xml = XML.parse(track_xml)
+
+ webvtt = <<-END_VTT
+ WEBVTT
+ Kind: captions
+ Language: #{track["languageCode"]}
+
+
+ END_VTT
+
+ track_xml.xpath_nodes("//transcript/text").each do |node|
+ start_time = node["start"].to_f.seconds
+ end_time = start_time + node["dur"].to_f.seconds
+
+ start_time = "#{start_time.hours.to_s.rjust(2, '0')}:#{start_time.minutes.to_s.rjust(2, '0')}:#{start_time.seconds.to_s.rjust(2, '0')}.#{start_time.milliseconds.to_s.rjust(3, '0')}"
+ end_time = "#{end_time.hours.to_s.rjust(2, '0')}:#{end_time.minutes.to_s.rjust(2, '0')}:#{end_time.seconds.to_s.rjust(2, '0')}.#{end_time.milliseconds.to_s.rjust(3, '0')}"
+
+ text = HTML.unescape(node.content)
+ if md = text.match(/(?<name>.*) : (?<text>.*)/)
+ text = "<v #{md["name"]}>#{md["text"]}</v>"
+ end
+
+ webvtt = webvtt + <<-END_CUE
+ #{start_time} --> #{end_time}
+ #{text}
+
+
+ END_CUE
+ end
+
+ webvtt
+end
+
get "/comments/:id" do |env|
id = env.params.url["id"]
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index 82087c53..91baafff 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -27,6 +27,11 @@
<source src="<%= fmt["url"] %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= i == 0 ? true : false %>">
<% end %>
<% end %>
+
+ <% captions.each do |caption| %>
+ <track kind="captions" src="/captions/<%= video.id %>?label=<%= caption["name"]["simpleText"] %>"
+ srclang="<%= caption["languageCode"] %>" label="<%= caption["name"]["simpleText"]%> ">
+ <% end %>
<% end %>
</video>
</div>
@@ -41,6 +46,7 @@ var options = {
'volumePanel',
'progressControl',
'remainingTimeDisplay',
+ 'captionsButton',
'qualitySelector',
'playbackRateMenuButton',
'fullscreenToggle',