diff --git a/assets/css/default.css b/assets/css/default.css
index 7db5a74a..90a7cc2e 100644
--- a/assets/css/default.css
+++ b/assets/css/default.css
@@ -874,4 +874,18 @@ h1, h2, h3, h4, h5, p,
.transcript-line:hover, .selected.transcript-line, .transcript-title-line:hover, .selected.transcript-title-line {
background: #cacaca;
+}
+
+.video-transcript > footer {
+ padding-bottom: 14px;
+ border-top: 1px solid #a0a0a0
+}
+
+.video-transcript > footer > form {
+ display: flex;
+ justify-content: center;
+}
+
+.video-transcript > footer select {
+ width: 75%;
}
\ No newline at end of file
diff --git a/locales/en-US.json b/locales/en-US.json
index 54ae6ab7..424dc08b 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -506,5 +506,6 @@
"video_description_show_transcript_section_button": "Show transcript",
"video_description_show_transcript_section_button_hide": "Hide transcript",
"error_transcripts_none_available": "No transcripts are available",
- "transcript_widget_title": "Transcript"
+ "transcript_widget_title": "Transcript",
+ "transcript_widget_no_js_change_transcript_btn": "Swap"
}
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index 57fb2029..04e1df63 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -43,6 +43,9 @@ module Invidious::Routes::Watch
show_transcripts ||= "0"
show_transcripts = show_transcripts == "1"
+ # Equal to a `caption.name` when set
+ selected_transcript = env.params.query["use_this_transcript"]?
+
preferences = env.get("preferences").as(Preferences)
user = env.get?("user").try &.as(User)
@@ -162,26 +165,55 @@ module Invidious::Routes::Watch
captions = captions - preferred_captions
if show_transcripts
- # The transcripts available are the exact same as the amount of captions available. Thus:
- if !preferred_captions.empty?
- chosen_transcript = preferred_captions[0]
- transcript_request_param = Invidious::Videos::Transcript.generate_param(
- id, chosen_transcript.language_code, chosen_transcript.auto_generated
- )
- elsif !captions.empty?
- chosen_transcript = captions[0]
- transcript_request_param = Invidious::Videos::Transcript.generate_param(
- id, chosen_transcript.language_code, chosen_transcript.auto_generated
- )
+ # Transcripts can be mapped 1:1 to a video's captions.
+ # As such the amount of transcripts available is the same as the amount of captions available.
+ #
+ # To request transcripts we have to give a language code, and a boolean dictating whether or not
+ # it is auto-generated. These attributes can be retrieved from the video's caption metadata.
+
+ # First we check if a transcript has been explicitly selected.
+ # The `use_this_transcript` url parameter provides the label of the transcript the user wants.
+ if selected_transcript
+ selected_transcript = URI.decode_www_form(selected_transcript)
+ target_transcript = captions.select(&.name.== selected_transcript)
else
- return error_template(404, "error_transcripts_none_available")
+ target_transcript = nil
end
- transcript = Invidious::Videos::Transcript.from_raw(
- YoutubeAPI.get_transcript(transcript_request_param),
- chosen_transcript.language_code,
- chosen_transcript.auto_generated,
+ # If the selected transcript has a match then we'll request that.
+ #
+ # If it does not match we'll try and request a transcript based on the user's
+ # preferred transcript
+ #
+ # If that also does not match then we'll just select the first transcript
+ # out of everything that's available.
+ #
+ # Raises when no matches are found
+ if target_transcript.is_a?(Array) && !target_transcript.empty?
+ target_transcript = target_transcript[0]
+ else
+ if !preferred_captions.empty?
+ target_transcript = preferred_captions[0]
+ elsif !captions.empty?
+ target_transcript = captions[0]
+ else
+ return error_template(404, "error_transcripts_none_available")
+ end
+ end
+
+ transcript_request_param = Invidious::Videos::Transcript.generate_param(
+ id, target_transcript.language_code, target_transcript.auto_generated
)
+
+ begin
+ transcript = Invidious::Videos::Transcript.from_raw(
+ YoutubeAPI.get_transcript(transcript_request_param),
+ target_transcript.language_code,
+ target_transcript.auto_generated,
+ )
+ rescue NotFoundException
+ return error_template(404, "error_transcripts_none_available")
+ end
else
transcript = nil
end
diff --git a/src/invidious/views/components/no-js-transcript-ui.ecr b/src/invidious/views/components/no-js-transcript-ui.ecr
index 743ea570..1622a47c 100644
--- a/src/invidious/views/components/no-js-transcript-ui.ecr
+++ b/src/invidious/views/components/no-js-transcript-ui.ecr
@@ -19,5 +19,28 @@
<% end %>
<% end %>
-
+
\ No newline at end of file