aboutsummaryrefslogtreecommitdiff
path: root/web/script/player/track/mse.ts
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-15 13:54:52 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-15 13:54:52 +0200
commitc59abb792391e2f7540a80bb8d989021fe0a5b80 (patch)
tree33688772e3822b38441f86a08c0c595ea1ef14b0 /web/script/player/track/mse.ts
parent3b147cb1dfcbd5c7218e0accd5784d992d5ae21c (diff)
downloadjellything-c59abb792391e2f7540a80bb8d989021fe0a5b80.tar
jellything-c59abb792391e2f7540a80bb8d989021fe0a5b80.tar.bz2
jellything-c59abb792391e2f7540a80bb8d989021fe0a5b80.tar.zst
refactor jsp, part 1
Diffstat (limited to 'web/script/player/track/mse.ts')
-rw-r--r--web/script/player/track/mse.ts63
1 files changed, 29 insertions, 34 deletions
diff --git a/web/script/player/track/mse.ts b/web/script/player/track/mse.ts
index d1a8c12..066bbfd 100644
--- a/web/script/player/track/mse.ts
+++ b/web/script/player/track/mse.ts
@@ -3,41 +3,41 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-import { JhlsTrackIndex, SourceTrack } from "../jhls.d.ts";
import { OVar } from "../../jshelper/mod.ts";
-import { profile_to_partial_track, track_to_content_type } from "../mediacaps.ts";
+import { track_to_content_type } from "../mediacaps.ts";
import { BufferRange, Player } from "../player.ts";
-import { EncodingProfileExt, ProfileSelector } from "../profiles.ts";
import { PlayerTrack, AppendRange, TARGET_BUFFER_DURATION, MIN_BUFFER_DURATION } from "./mod.ts";
-import { show_profile } from "../mod.ts";
import { e } from "../../jshelper/src/element.ts";
+import { FormatInfo, FragmentIndex, StreamContainer, TrackInfo } from "../types_stream.ts";
+
+interface UsableFormat { format_index: number, usable_index: number, format: FormatInfo, container: StreamContainer }
export class MSEPlayerTrack extends PlayerTrack {
public source_buffer!: SourceBuffer;
private current_load?: AppendRange;
private loading = new Set<number>();
private append_queue: AppendRange[] = [];
- public profile_selector: ProfileSelector;
- public profile = new OVar<EncodingProfileExt | undefined>(undefined);
- public index?: JhlsTrackIndex
+ public index?: FragmentIndex
+ public active_format = new OVar<UsableFormat | undefined>(undefined);
+ public usable_formats: UsableFormat[] = []
constructor(
private player: Player,
- private node_id: string,
+ private base_url: string,
+ private segment_index: number,
track_index: number,
- public metadata: SourceTrack,
+ public trackinfo: TrackInfo,
) {
super(track_index);
- this.profile_selector = new ProfileSelector(player, this, player.downloader.bandwidth_avail);
this.init()
}
async init() {
this.buffered.value = [{ start: 0, end: this.player.duration.value, status: "loading" }]
try {
- const res = await fetch(`/n/${encodeURIComponent(this.node_id)}/stream?format=jhlsi&track=${this.track_index}`, { headers: { "Accept": "application/json" } });
+ const res = await fetch(`${this.base_url}?fragmentindex&segment=${this.segment_index}&track=${this.track_index}`, { headers: { "Accept": "application/json" } });
if (!res.ok) return this.player.error.value = "Cannot download index.", undefined;
- let index!: JhlsTrackIndex & { error: string; };
+ let index!: FragmentIndex & { error: string; };
try { index = await res.json(); }
catch (_) { this.player.set_pers("Error: Failed to fetch node"); }
if (index.error) return this.player.set_pers("server error: " + index.error), undefined;
@@ -49,10 +49,9 @@ export class MSEPlayerTrack extends PlayerTrack {
}
this.buffered.value = []
- const canplay = await this.profile_selector.select_optimal_profile(this.track_index, this.profile);
- if (!canplay) return this.player.set_track_enabled(this.track_index, false)
- const ct = track_to_content_type(this.track_from_profile())!;
- console.log(`track ${this.track_index} source buffer content-type: ${ct}`);
+ this.active_format.value = { usable_index: 0, format_index: 0, container: "webm", format: this.trackinfo.formats[0] }
+
+ const ct = track_to_content_type(this.active_format.value!.format, this.active_format.value!.container);
this.source_buffer = this.player.media_source.addSourceBuffer(ct);
this.abort.signal.addEventListener("abort", () => {
console.log(`destroy source buffer for track ${this.track_index}`);
@@ -81,10 +80,6 @@ export class MSEPlayerTrack extends PlayerTrack {
this.update(this.player.video.currentTime)
}
- track_from_profile(): SourceTrack {
- if (this.profile.value) return profile_to_partial_track(this.profile.value);
- else return this.metadata;
- }
update_buf_ranges() {
if (!this.index) return;
@@ -97,7 +92,7 @@ export class MSEPlayerTrack extends PlayerTrack {
});
}
for (const r of this.loading) {
- ranges.push({ ...this.index.fragments[r], status: "loading" });
+ ranges.push({ ...this.index[r], status: "loading" });
}
this.buffered.value = ranges;
}
@@ -107,8 +102,8 @@ export class MSEPlayerTrack extends PlayerTrack {
this.update_buf_ranges(); // TODO required?
const blocking = [];
- for (let i = 0; i < this.index.fragments.length; i++) {
- const frag = this.index.fragments[i];
+ for (let i = 0; i < this.index.length; i++) {
+ const frag = this.index[i];
if (frag.end < target) continue;
if (frag.start >= target + TARGET_BUFFER_DURATION) break;
if (!this.check_buf_collision(frag.start, frag.end)) continue;
@@ -129,13 +124,13 @@ export class MSEPlayerTrack extends PlayerTrack {
async load(index: number) {
this.loading.add(index);
- await this.profile_selector.select_optimal_profile(this.track_index, this.profile);
- const url = `/n/${encodeURIComponent(this.node_id)}/stream?format=frag&webm=true&track=${this.track_index}&index=${index}${this.profile.value ? `&profile=${this.profile.value.id}` : ""}`;
+ // TODO update format selection
+ const url = `${this.base_url}?fragment&segment=${this.segment_index}&track=${this.track_index}&format=${this.active_format.value!.format_index}&index=${index}&container=${this.active_format.value!.container}`;
const buf = await this.player.downloader.download(url);
await new Promise<void>(cb => {
if (!this.index) return;
if (this.abort.signal.aborted) return;
- this.append_queue.push({ buf, ...this.index.fragments[index], index, cb });
+ this.append_queue.push({ buf, ...this.index[index], index, cb });
this.tick_append();
});
}
@@ -146,8 +141,8 @@ export class MSEPlayerTrack extends PlayerTrack {
this.append_queue.splice(0, 1);
this.current_load = frag;
// TODO why is appending so unreliable?! sometimes it does not add it
- this.source_buffer.changeType(track_to_content_type(this.track_from_profile())!);
- this.source_buffer.timestampOffset = this.profile.value !== undefined ? frag.start : 0
+ this.source_buffer.changeType(track_to_content_type(this.active_format.value!.format, this.active_format.value!.container));
+ this.source_buffer.timestampOffset = this.active_format.value !== undefined ? frag.start : 0
console.log(`append track ${this.track_index}`);
this.source_buffer.appendBuffer(frag.buf);
}
@@ -158,13 +153,13 @@ export class MSEPlayerTrack extends PlayerTrack {
const c = b.filter(r => r.status == t);
return `${c.length} range${c.length != 1 ? "s" : ""}, ${c.reduce((a, v) => a + v.end - v.start, 0).toFixed(2)}s`
}
- return this.profile.liftA2(this.buffered, (p, b) =>
+ return this.active_format.liftA2(this.buffered, (p, b) =>
e("pre",
- `mse track ${this.track_index}: ${(p ? `profile ${p.id} (${show_profile(p)})` : `remux`)}`
- + `\n\ttype: ${track_to_content_type(this.track_from_profile())}`
- + `\n\tbuffered: ${rtype("buffered", b)}`
- + `\n\tqueued: ${rtype("queued", b)}`
- + `\n\tloading: ${rtype("loading", b)}`
+ p ?
+ `mse track ${this.track_index}: format ${p.format_index} (${p.format.remux ? "remux" : "transcode"})`
+ + `\n\ttype: ${track_to_content_type(p.format, p.container)} br=${p.format.bitrate}`
+ + `\n\tbuffered: ${rtype("buffered", b)} / queued: ${rtype("queued", b)} / loading: ${rtype("loading", b)}`
+ : ""
) as HTMLElement
)
}