aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-10-01 23:07:35 +0200
committermetamuffin <metamuffin@disroot.org>2023-10-01 23:07:35 +0200
commit4b6dbed857754a13b0b8776ab9ec583e093d548b (patch)
tree8986b2d3be049fce865ec3ae6ebfefe9f23f16a8
parent29c3289bd8441dbe40a91fd7089838730f9fc47f (diff)
downloadjellything-4b6dbed857754a13b0b8776ab9ec583e093d548b.tar
jellything-4b6dbed857754a13b0b8776ab9ec583e093d548b.tar.bz2
jellything-4b6dbed857754a13b0b8776ab9ec583e093d548b.tar.zst
proper seeking without bugs (so far)
-rw-r--r--web/script/player/mod.ts35
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)