diff options
-rw-r--r-- | web/script/player/mod.ts | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/web/script/player/mod.ts b/web/script/player/mod.ts index 17cd77e..1a977e2 100644 --- a/web/script/player/mod.ts +++ b/web/script/player/mod.ts @@ -148,7 +148,7 @@ function display_time(t: number): string { return (h ? h + "h" : "") + (m ? m + "m" : "") + (s ? s + "s" : "") } -interface BufferRange extends Range { status: "buffered" | "downloading" | "queued" } +interface BufferRange extends Range { status: "buffered" | "loading" | "queued" } class Player { public video = e("video") private media_source = new MediaSource(); @@ -169,7 +169,8 @@ class Player { this.update() // TODO maybe not here } this.video.onplay = () => { - this.buffering_status.value = undefined; + console.log("play"); + this.buffering_status.value = "Resuming playback..."; } this.video.onwaiting = () => { console.log("waiting"); @@ -177,16 +178,27 @@ class Player { this.canplay.value = false; } this.video.onplaying = () => { + console.log("playing"); this.playing.value = true; + this.buffering_status.value = undefined; } this.video.onpause = () => { + console.log("pause"); this.playing.value = false } this.video.oncanplay = () => { - this.buffering_status.value = undefined console.log("canplay"); + this.buffering_status.value = undefined this.canplay.value = true } + this.video.onseeking = () => { + console.log("seeking"); + this.buffering_status.value = "Seeking..." + } + this.video.onseeked = () => { + console.log("seeked"); + this.buffering_status.value = undefined + } this.fetch_meta() } @@ -214,18 +226,15 @@ class Player { } play() { - console.log("play"); this.video.play() } pause() { - console.log("pause"); this.video.pause() } async seek(p: number) { - this.pause() + this.buffering_status.value = "Buffering at target..." await this.update(p) this.video.currentTime = p - this.play() } } @@ -264,7 +273,7 @@ class PlayerTrack { }) } for (const r of this.loading) { - ranges.push({ ...this.metadata.segments[r], status: "downloading" }) + ranges.push({ ...this.metadata.segments[r], status: "loading" }) } this.buffered.value = ranges } @@ -272,27 +281,29 @@ class PlayerTrack { async update(target: number) { this.update_buf_ranges() // TODO required? + const blocking = [] for (let i = 0; i < this.metadata.segments.length; i++) { const seg = this.metadata.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 if (seg.start <= target + MIN_BUFFER_DURATION) - await this.load(i) + blocking.push(this.load(i)) else this.load(i) } + await Promise.all(blocking) } check_buf_collision(start: number, end: number) { + const EPSILON = 0.01 for (const r of this.buffered.value) - if (r.end > start && r.start < end) + if (r.end - EPSILON > start && r.start < end - EPSILON) return false return true } async load(index: number) { this.loading.add(index) - console.log("load", index); const res = await fetch(`/n/${encodeURIComponent(this.node_id)}/stream?format=hlsseg&tracks=${this.track_index}&index=${index}`) if (!res.ok) throw new Error(`segment fail i=${index} t=${this.track_index}`); const buf = await res.arrayBuffer() @@ -303,11 +314,9 @@ class PlayerTrack { }) } tick_append() { - // console.log("tick", this.append_queue); if (this.source_buffer.updating) return if (this.append_queue.length) { const seg = this.append_queue[0]; - // console.log("append", this.track_index, seg); this.source_buffer.timestampOffset = seg.start this.source_buffer.appendBuffer(seg.buf); this.append_queue.splice(0, 1) |