aboutsummaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-17 17:26:27 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-17 17:26:27 +0200
commitf9c95732f65d96103e253ec8716e73eb501a801a (patch)
tree936efd08fdac497ee6eb6ca40ecf1a11a20ec968 /web
parent3f04466df27cb032a91e304eca1b3e91aad47cb4 (diff)
downloadjellything-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.ts69
-rw-r--r--web/script/player/track/vtt.ts8
-rw-r--r--web/script/player/types_stream.ts2
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 {