diff options
Diffstat (limited to 'web/script/player/track.ts')
-rw-r--r-- | web/script/player/track.ts | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/web/script/player/track.ts b/web/script/player/track.ts index e95ba85..c6f90b4 100644 --- a/web/script/player/track.ts +++ b/web/script/player/track.ts @@ -3,12 +3,11 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin <metamuffin.org> */ -import { SourceTrack, TimeRange } from "./jhls.d.ts"; +import { JhlsTrackIndex, SourceTrack, TimeRange } from "./jhls.d.ts"; import { OVar } from "../jshelper/mod.ts"; -import { JhlsTrack } from "./jhls.d.ts"; import { profile_to_partial_track, track_to_content_type } from "./mediacaps.ts"; import { BufferRange, Player } from "./player.ts"; -import { EncodingProfileExt } from "./profiles.ts"; +import { EncodingProfileExt, ProfileSelector } from "./profiles.ts"; export const TARGET_BUFFER_DURATION = 10 export const MIN_BUFFER_DURATION = 1 @@ -22,9 +21,17 @@ export class PlayerTrack { public buffered = new OVar<BufferRange[]>([]); private append_queue: AppendRange[] = []; public profile = new OVar<EncodingProfileExt | undefined>(undefined); + public profile_selector: ProfileSelector - public static async new(player: Player, node_id: string, track_index: number, metadata: JhlsTrack) { - const t = new PlayerTrack(player, node_id, track_index, metadata) + public static async new(player: Player, node_id: string, track_index: number, metadata: SourceTrack): Promise<PlayerTrack | undefined> { + const res = await fetch(`/n/${encodeURIComponent(player.node_id)}/stream?format=jhlsi&tracks=${track_index}`, { headers: { "Accept": "application/json" } }) + if (!res.ok) return player.error.value = "Cannot download node.", undefined + let index!: JhlsTrackIndex & { error: string } + try { index = await res.json() } + catch (_) { player.set_pers("Error: Failed to fetch node") } + if (index.error) return player.set_pers("server error: " + index.error), undefined + + const t = new PlayerTrack(player, node_id, track_index, metadata, index) await t.init() return t } @@ -32,10 +39,13 @@ export class PlayerTrack { private player: Player, private node_id: string, private track_index: number, - private metadata: JhlsTrack - ) { } + private metadata: SourceTrack, + public index: JhlsTrackIndex, + ) { + this.profile_selector = new ProfileSelector(player, this, player.downloader.bandwidth) + } async init() { - await this.player.profile_selector.select_optimal_profile(this.track_index, this.profile); + await this.profile_selector.select_optimal_profile(this.track_index, this.profile); const ct = track_to_content_type(this.track_from_profile())! console.log(`track ${this.track_index} source buffer content-type: ${ct}`); this.source_buffer = this.player.media_source.addSourceBuffer(ct); @@ -63,7 +73,7 @@ export class PlayerTrack { track_from_profile(): SourceTrack { if (this.profile.value) return profile_to_partial_track(this.profile.value) - else return this.metadata.info + else return this.metadata } update_buf_ranges() { @@ -76,7 +86,7 @@ export class PlayerTrack { }); } for (const r of this.loading) { - ranges.push({ ...this.metadata.segments[r], status: "loading" }); + ranges.push({ ...this.index.segments[r], status: "loading" }); } this.buffered.value = ranges; } @@ -85,8 +95,8 @@ export class PlayerTrack { this.update_buf_ranges(); // TODO required? const blocking = []; - for (let i = 0; i < this.metadata.segments.length; i++) { - const seg = this.metadata.segments[i]; + for (let i = 0; i < this.index.segments.length; i++) { + const seg = this.index.segments[i]; if (seg.end < target) continue; if (seg.start >= target + TARGET_BUFFER_DURATION) break; if (!this.check_buf_collision(seg.start, seg.end)) continue; @@ -107,11 +117,11 @@ export class PlayerTrack { async load(index: number) { this.loading.add(index); - await this.player.profile_selector.select_optimal_profile(this.track_index, this.profile); - const url = `/n/${encodeURIComponent(this.node_id)}/stream?format=hlsseg&webm=true&tracks=${this.track_index}&index=${index}${this.profile.value ? `&profile=${this.profile.value.id}` : ""}`; + await this.profile_selector.select_optimal_profile(this.track_index, this.profile); + const url = `/n/${encodeURIComponent(this.node_id)}/stream?format=snippet&webm=true&tracks=${this.track_index}&index=${index}${this.profile.value ? `&profile=${this.profile.value.id}` : ""}`; const buf = await this.player.downloader.download(url); await new Promise<void>(cb => { - this.append_queue.push({ buf, ...this.metadata.segments[index], index, cb }); + this.append_queue.push({ buf, ...this.index.segments[index], index, cb }); this.tick_append(); }); } @@ -125,7 +135,6 @@ export class PlayerTrack { this.source_buffer.changeType(track_to_content_type(this.track_from_profile())!); this.source_buffer.timestampOffset = seg.start; this.source_buffer.appendBuffer(seg.buf); - } } } |