aboutsummaryrefslogtreecommitdiff
path: root/web/script/player/track/vtt.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web/script/player/track/vtt.ts')
-rw-r--r--web/script/player/track/vtt.ts96
1 files changed, 0 insertions, 96 deletions
diff --git a/web/script/player/track/vtt.ts b/web/script/player/track/vtt.ts
deleted file mode 100644
index 2152b97..0000000
--- a/web/script/player/track/vtt.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- This file is part of jellything (https://codeberg.org/metamuffin/jellything)
- which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
- Copyright (C) 2026 metamuffin <metamuffin.org>
-*/
-import { e } from "../../jshelper/src/element.ts";
-import { Player } from "../player.ts";
-import { SubtitleCue, TrackInfo } from "../types_stream.ts";
-import { PlayerTrack } from "./mod.ts";
-
-export class VttPlayerTrack extends PlayerTrack {
- private track: TextTrack;
- public cues?: SubtitleCue[]
-
- constructor(
- private player: Player,
- private node_id: string,
- track_index: number,
- private track_info: TrackInfo,
- ) {
- super(track_index);
- this.track = this.player.video.addTextTrack("subtitles", this.track_info.name, this.track_info.language);
- this.buffered.value = [{ start: 0, end: this.player.duration.value, status: "loading" }]
- this.init()
- }
-
- private on_ready() {
- if (!this.cues) return
- this.buffered.value = [{ start: 0, end: this.player.duration.value, status: "buffered" }]
- for (const cue of this.cues) {
- this.track.addCue(create_cue(cue));
- }
- this.track.mode = "showing";
- this.abort.signal.addEventListener("abort", () => {
- // TODO disable subtitles properly
- this.track.mode = "hidden";
- });
- }
-
- async init() {
- try {
- const res = await fetch(`${this.player.base_url}?format=remux&segment=0&container=jvtt&track=${this.track_index}`, { headers: { "Accept": "application/json" } });
- if (!res.ok) return this.player.error.value = "Cannot download index.", undefined;
- let ai!: SubtitleCue[] & { error: string; };
- try { ai = await res.json(); }
- catch (_) { this.player.set_pers("Error: Failed to fetch node"); }
- if (ai.error) return this.player.set_pers("server error: " + ai.error), undefined;
- this.cues = ai;
- } catch (e) {
- if (e instanceof TypeError) {
- this.player.set_pers("Cannot download subtitles: Network Error");
- return undefined
- } else throw e;
- }
- this.on_ready()
- }
-
- public debug(): HTMLElement {
- return e("pre", `vtt track ${this.track_index}\n\t${this.cues?.length} cues loaded`)
- }
-}
-
-function create_cue(cue: SubtitleCue): VTTCue {
- const c = new VTTCue(cue.start, cue.end, cue.content);
- const props = parse_layout_properties(cue.content.split("\n")[0])
- if (props) {
- c.text = cue.content.split("\n").slice(1).join("\n")
- // TODO re-enable when it works
- // // TODO this does not work at all...
- // const region = new VTTRegion()
- // if ("position" in props && props.position.endsWith("%"))
- // region.regionAnchorX = parseFloat(props.position.replace("%", ""))
- // if ("line" in props && props.line.endsWith("%"))
- // region.regionAnchorY = parseFloat(props.line.replace("%", ""))
- // if ("align" in props)
- // c.align = props.align as AlignSetting
- // c.region = region
- } else {
- c.line = -2;
- }
- return c
-}
-
-function parse_layout_properties(s: string): undefined | Record<string, string> {
- const o: Record<string, string> = {}
- for (const tok of s.split(" ")) {
- const [k, v, ...rest] = tok.split(":")
- if (!v || rest.length) return undefined
- o[k] = v
- }
- // some common keys to prevent false positives
- if ("position" in o) return o
- if ("align" in o) return o
- if ("line" in o) return o
- return undefined
-}