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