diff options
author | metamuffin <metamuffin@disroot.org> | 2025-04-17 17:26:27 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-04-17 17:26:27 +0200 |
commit | f9c95732f65d96103e253ec8716e73eb501a801a (patch) | |
tree | 936efd08fdac497ee6eb6ca40ecf1a11a20ec968 /web | |
parent | 3f04466df27cb032a91e304eca1b3e91aad47cb4 (diff) | |
download | jellything-f9c95732f65d96103e253ec8716e73eb501a801a.tar jellything-f9c95732f65d96103e253ec8716e73eb501a801a.tar.bz2 jellything-f9c95732f65d96103e253ec8716e73eb501a801a.tar.zst |
jsp: re-add chapters
Diffstat (limited to 'web')
-rw-r--r-- | web/script/player/mod.ts | 69 | ||||
-rw-r--r-- | web/script/player/track/vtt.ts | 8 | ||||
-rw-r--r-- | web/script/player/types_stream.ts | 2 |
3 files changed, 44 insertions, 35 deletions
diff --git a/web/script/player/mod.ts b/web/script/player/mod.ts index e8cde94..32ad355 100644 --- a/web/script/player/mod.ts +++ b/web/script/player/mod.ts @@ -10,7 +10,7 @@ import { Logger } from "../jshelper/src/log.ts"; import { Player } from "./player.ts"; import { Popup } from "./popup.ts"; import { Playersync, playersync_controls } from "./sync.ts" -import { WatchedState } from "./types_node.ts"; +import { Chapter, NodePublic, NodeUserData } from "./types_node.ts"; import { FormatInfo, TrackKind } from "./types_stream.ts"; globalThis.addEventListener("DOMContentLoaded", () => { @@ -36,10 +36,10 @@ function toggle_fullscreen() { else document.documentElement.requestFullscreen() } -function get_continue_time(w: WatchedState): number { - if (typeof w == "string") return 0 - else return w.progress -} +// function get_continue_time(w: WatchedState): number { +// if (typeof w == "string") return 0 +// else return w.progress +// } function get_query_start_time() { const u = new URL(globalThis.location.href) @@ -57,6 +57,19 @@ function initialize_player(node_id: string): HTMLElement { const show_stats = new OVar(false); const idle_inhibit = new OVar(false) const sync_state = new OVar<Playersync | undefined>(undefined) + const chapters = new OVar<Chapter[]>([]) + + fetch(`/n/${node_id}`, { headers: { Accept: "application/json" } }) + .then(res => { + if (!res.ok) throw "a" + return res.json() + }) + .catch(() => logger.log_persistent("Node data failed to download")) + .then(ndata_ => { + const ndata = ndata_ as { node: NodePublic, userdata: NodeUserData } + console.log(ndata.node.media!.chapters); + chapters.value = ndata.node.media!.chapters + }) //@ts-ignore for debugging globalThis.player = player; @@ -196,16 +209,15 @@ function initialize_player(node_id: string): HTMLElement { ), pri = e("div", { class: "jsp-pri" }, pri_current = e("div", { class: "jsp-pri-current" }), - // TODO - // player.chapters.map( - // chapters => e("div", ...chapters.map(chap => e("div", { - // class: "jsp-chapter", - // style: { - // left: pri_map(chap.time_start ?? 0), - // width: pri_map((chap.time_end ?? player.duration.value) - (chap.time_start ?? 0)) - // } - // }, e("p", chap.labels[0][1])))) - // ), + chapters.liftA2(player.duration, + (chapters, duration) => e("div", ...chapters.map(chap => e("div", { + class: "jsp-chapter", + style: { + left: pri_map(chap.time_start ?? 0), + width: pri_map((chap.time_end ?? duration) - (chap.time_start ?? 0)) + } + }, e("p", chap.labels[0][1])))) + ), player.active_tracks.map( tracks => e("div", ...tracks.map((t, i) => t.buffered.map( ranges => e("div", ...ranges.map( @@ -287,8 +299,8 @@ function initialize_player(node_id: string): HTMLElement { else if (k.code == "ArrowRight") player.seek(player.position.value + 5) else if (k.code == "ArrowUp") player.seek(player.position.value - 60) else if (k.code == "ArrowDown") player.seek(player.position.value + 60) - // else if (k.code == "PageUp") player.seek(find_closest_chaps(player).prev?.time_start ?? 0) - // else if (k.code == "PageDown") player.seek(find_closest_chaps(player).next?.time_start ?? player.duration.value) + else if (k.code == "PageUp") player.seek(find_closest_chaps(player.position.value, chapters.value).prev?.time_start ?? 0) + else if (k.code == "PageDown") player.seek(find_closest_chaps(player.position.value, chapters.value).next?.time_start ?? player.duration.value) else return; k.preventDefault() }) @@ -366,16 +378,13 @@ export function show_volume(v: number): string { return `${v == 0 ? "-∞" : (Math.log10(v) * 10).toFixed(2)}dB | ${(v * 100).toFixed(2)}%` } -// TODO -// function find_closest_chaps(player: Player) { -// const now = player.position.value -// const chaps = player.chapters.value -// let prev, next; -// for (const c of chaps) { -// const t_start = (c.time_start ?? 0) -// next = c; -// if (t_start > now) break -// prev = c; -// } -// return { next, prev } -// } +function find_closest_chaps(position: number, chapters: Chapter[]) { + let prev, next; + for (const c of chapters) { + const t_start = (c.time_start ?? 0) + next = c; + if (t_start > position) break + prev = c; + } + return { next, prev } +} diff --git a/web/script/player/track/vtt.ts b/web/script/player/track/vtt.ts index 3dd7670..e89bf24 100644 --- a/web/script/player/track/vtt.ts +++ b/web/script/player/track/vtt.ts @@ -5,12 +5,12 @@ */ import { e } from "../../jshelper/src/element.ts"; import { Player } from "../player.ts"; -import { JvttCue, TrackInfo } from "../types_stream.ts"; +import { SubtitleCue, TrackInfo } from "../types_stream.ts"; import { PlayerTrack } from "./mod.ts"; export class VttPlayerTrack extends PlayerTrack { private track: TextTrack; - public cues?: JvttCue[] + public cues?: SubtitleCue[] constructor( private player: Player, @@ -41,7 +41,7 @@ export class VttPlayerTrack extends PlayerTrack { try { const res = await fetch(`/n/${encodeURIComponent(this.node_id)}/stream?format=jvtt&track=${this.track_index}`, { headers: { "Accept": "application/json" } }); if (!res.ok) return this.player.error.value = "Cannot download index.", undefined; - let ai!: JvttCue[] & { error: string; }; + 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; @@ -60,7 +60,7 @@ export class VttPlayerTrack extends PlayerTrack { } } -function create_cue(cue: JvttCue): VTTCue { +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) { diff --git a/web/script/player/types_stream.ts b/web/script/player/types_stream.ts index 290a778..9565bf4 100644 --- a/web/script/player/types_stream.ts +++ b/web/script/player/types_stream.ts @@ -5,7 +5,7 @@ */ export type FragmentIndex = TimeRange[] export interface TimeRange { start: number, end: number } -export interface JvttCue extends TimeRange { +export interface SubtitleCue extends TimeRange { content: string } export interface StreamInfo { |