From c59abb792391e2f7540a80bb8d989021fe0a5b80 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 15 Apr 2025 13:54:52 +0200 Subject: refactor jsp, part 1 --- web/script/player/mod.ts | 88 ++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 36 deletions(-) (limited to 'web/script/player/mod.ts') diff --git a/web/script/player/mod.ts b/web/script/player/mod.ts index 15c37da..82ee287 100644 --- a/web/script/player/mod.ts +++ b/web/script/player/mod.ts @@ -7,11 +7,11 @@ import { OVar, show } from "../jshelper/mod.ts"; import { e } from "../jshelper/mod.ts"; import { Logger } from "../jshelper/src/log.ts"; -import { EncodingProfile } from "./jhls.d.ts"; -import { TrackKind, get_track_kind } from "./mediacaps.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 { FormatInfo, TrackKind } from "./types_stream.ts"; globalThis.addEventListener("DOMContentLoaded", () => { if (document.body.classList.contains("player")) { @@ -36,12 +36,26 @@ 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_query_start_time() { + const u = new URL(globalThis.location.href) + const p = u.searchParams.get("t") + if (!p) return + const x = parseFloat(p) + if (Number.isNaN(x)) return + return x +} function initialize_player(el: HTMLElement, node_id: string) { el.innerHTML = "" // clear the body const logger = new Logger(s => e("p", s)) - const player = new Player(node_id, logger) + const start_time = get_query_start_time() ?? 0 // TODO get_continue_time(ndata.userdata.watched); + const player = new Player(`/n/${encodeURIComponent(node_id)}/stream`, `/n/${encodeURIComponent(node_id)}/poster`, start_time, logger) const show_stats = new OVar(false); const idle_inhibit = new OVar(false) const sync_state = new OVar(undefined) @@ -72,13 +86,13 @@ function initialize_player(el: HTMLElement, node_id: string) { const step_track_kind = (kind: TrackKind) => { // TODO cycle through all of them const active = player.active_tracks.value.filter( - ts => get_track_kind(player.tracks![ts.track_index].kind) == kind) + ts => player.tracks![ts.track_index].kind == kind) if (active.length > 0) { for (const t of active) player.set_track_enabled(t.track_index, false) } else { const all_kind = (player.tracks ?? []) .map((track, index) => ({ index, track })) - .filter(({ track }) => get_track_kind(track.kind) == kind) + .filter(({ track }) => track.kind == kind) if (all_kind.length < 1) return logger.log(`No ${kind} tracks available`) player.set_track_enabled(all_kind[0].index, true) } @@ -92,7 +106,7 @@ function initialize_player(el: HTMLElement, node_id: string) { const track_select = (kind: TrackKind) => { const button = e("div", player.active_tracks.map(_ => { const active = player.active_tracks.value.filter( - ts => get_track_kind(player.tracks![ts.track_index].kind) == kind) + ts => player.tracks![ts.track_index].kind == kind) const enabled = active.length > 0 return e("button", MEDIA_KIND_ICONS[kind][+enabled], { class: "icon", @@ -105,7 +119,7 @@ function initialize_player(el: HTMLElement, node_id: string) { } else { const all_kind = (player.tracks ?? []) .map((track, index) => ({ index, track })) - .filter(({ track }) => get_track_kind(track.kind) == kind) + .filter(({ track }) => track.kind == kind) if (all_kind.length < 1) return player.set_track_enabled(all_kind[0].index, true) } @@ -138,7 +152,7 @@ function initialize_player(el: HTMLElement, node_id: string) { player.active_tracks.map(_ => { const tracks_avail = (player.tracks ?? []) .map((track, index) => ({ index, track })) - .filter(({ track }) => get_track_kind(track.kind) == kind); + .filter(({ track }) => track.kind == kind); if (!tracks_avail.length) return e("p", `No ${kind} tracks available.`) as HTMLElement; return e("ul", { class: "jsp-track-list" }, ...tracks_avail .map(({ track, index }): HTMLElement => { @@ -184,15 +198,16 @@ function initialize_player(el: HTMLElement, node_id: string) { ), pri = e("div", { class: "jsp-pri" }, pri_current = e("div", { class: "jsp-pri-current" }), - 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])))) - ), + // 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])))) + // ), player.active_tracks.map( tracks => e("div", ...tracks.map((t, i) => t.buffered.map( ranges => e("div", ...ranges.map( @@ -275,8 +290,8 @@ function initialize_player(el: HTMLElement, node_id: string) { 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).prev?.time_start ?? 0) + // else if (k.code == "PageDown") player.seek(find_closest_chaps(player).next?.time_start ?? player.duration.value) else return; k.preventDefault() }) @@ -339,25 +354,26 @@ function mouse_idle(e: HTMLElement, timeout: number): OVar { return idle } -export function show_profile(profile: EncodingProfile): string { - if (profile.audio) return `codec=${profile.audio.codec} br=${show.metric(profile.audio.bitrate, "b/s")}${profile.audio.sample_rate ? ` sr=${show.metric(profile.audio.sample_rate, "Hz")}` : ""}` - if (profile.video) return `codec=${profile.video.codec} br=${show.metric(profile.video.bitrate, "b/s")} w=${profile.video.width} preset=${profile.video.preset}` - if (profile.subtitles) return `codec=${profile.subtitles.codec}` - return `???` +export function show_format(format: FormatInfo): string { + // if (format.audio) return `codec=${format.audio.codec} br=${show.metric(format.audio.bitrate, "b/s")}${format.audio.sample_rate ? ` sr=${show.metric(format.audio.sample_rate, "Hz")}` : ""}` + // if (format.video) return `codec=${format.video.codec} br=${show.metric(format.video.bitrate, "b/s")} w=${format.video.width} preset=${format.video.preset}` + // if (format.subtitles) return `codec=${format.subtitles.codec}` + return `TODO` } export function show_volume(v: number): string { return `${v == 0 ? "-∞" : (Math.log10(v) * 10).toFixed(2)}dB | ${(v * 100).toFixed(2)}%` } -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 } -} +// 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 } +// } -- cgit v1.2.3-70-g09d2