Merge branch 'transcripts-support'
Some checks failed
Build and release container directly from master / release (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.12.1, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.13.2, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.14.0, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (1.15.0, true) (push) Has been cancelled
Invidious CI / build - crystal: ${{ matrix.crystal }}, stable: ${{ matrix.stable }} (nightly, false) (push) Has been cancelled
Invidious CI / build-docker (push) Has been cancelled
Invidious CI / build-docker-arm64 (push) Has been cancelled
Invidious CI / lint (push) Has been cancelled

From: https://github.com/iv-org/invidious/pull/5298/
This commit is contained in:
Fijxu
2025-05-13 11:31:21 -04:00
8 changed files with 228 additions and 5 deletions

View File

@@ -38,6 +38,14 @@ module Invidious::Routes::Watch
nojs ||= "0"
nojs = nojs == "1"
show_transcripts = env.params.query["show_transcripts"]?
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)
@@ -172,6 +180,60 @@ module Invidious::Routes::Watch
}
captions = captions - preferred_captions
if show_transcripts
# 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
target_transcript = nil
end
# 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
aspect_ratio = "16:9"
thumbnail = "/vi/#{video.id}/maxres.jpg"