diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/script/player/mod.ts | 6 | ||||
-rw-r--r-- | web/script/player/profiles.ts | 29 | ||||
-rw-r--r-- | web/script/player/track.ts | 5 |
3 files changed, 26 insertions, 14 deletions
diff --git a/web/script/player/mod.ts b/web/script/player/mod.ts index 89919e4..e6d3ea0 100644 --- a/web/script/player/mod.ts +++ b/web/script/player/mod.ts @@ -69,7 +69,7 @@ function initialize_player(el: HTMLElement, node_id: string) { )), show_stats.map(do_show => player.tracks.map(tracks => !do_show ? e("div") : e("div", { class: "jsp-stats" }, - player.downloader.bandwidth.map(b => e("pre", `estimated bandwidth: ${show.metric(b, "B/s")}`)), + player.downloader.bandwidth.map(b => e("pre", `estimated bandwidth: ${show.metric(b, "B/s")} / ${show.metric(b * 8, "b/s")}`)), ...tracks.map((t, i) => t.profile.map(p => e("pre", `track ${i}: ` + (p ? `profile ${p.id} (${show_profile(p)})` : `remux`)) )) @@ -122,8 +122,8 @@ function mouse_idle(e: HTMLElement, timeout: number, cb: (b: boolean) => unknown } function show_profile(profile: EncodingProfile): string { - if (profile.audio) return `codec=${profile.audio.codec} ar=${show.metric(profile.audio.sample_rate ?? -1, "Hz")} abr=${show.metric(profile.audio.bitrate, "b/s")}` + if (profile.audio) return `codec=${profile.audio.codec} ${profile.audio.sample_rate ? `ar=${show.metric(profile.audio.sample_rate, "Hz")} ` : ""}abr=${show.metric(profile.audio.bitrate, "b/s")}` if (profile.video) return `codec=${profile.video.codec} vw=${profile.video.width} vbr=${show.metric(profile.video.bitrate, "b/s")} preset=${profile.video.preset}` if (profile.subtitles) return `codec=${profile.subtitles.codec}` return `???` -}
\ No newline at end of file +} diff --git a/web/script/player/profiles.ts b/web/script/player/profiles.ts index b4de534..50be9d3 100644 --- a/web/script/player/profiles.ts +++ b/web/script/player/profiles.ts @@ -1,6 +1,8 @@ import { OVar } from "../jshelper/mod.ts"; import { EncodingProfile, JhlsMetadata } from "./jhls.d.ts"; +const PROFILE_UP_FAC = 0.7 + export interface EncodingProfileExt extends EncodingProfile { id: number, order: number } export class ProfileSelector { profiles_video: EncodingProfileExt[] = [] @@ -30,17 +32,26 @@ export class ProfileSelector { return [] } select_optimal_profile(track: number, profile: OVar<EncodingProfileExt | undefined>) { - if (this.bandwidth.value < 5000 * 1000) { - profile.value = this.profile_list_for_track(track)[0] - } else { - profile.value = undefined + const profs = this.profile_list_for_track(track) + + const co = profile.value?.order ?? -1 + const current_bitrate = profile_bw(profs[co], 5000 * 1000) + const next_bitrate = profile_bw(profs[co - 1], 5000 * 1000) + console.log({ current_bitrate, next_bitrate, co, bandwidth: this.bandwidth.value * 8 }); + if (current_bitrate > this.bandwidth.value * 8 && co + 1 < profs.length) { + console.log("profile up"); + profile.value = profs[co + 1] + } + if (next_bitrate < this.bandwidth.value * 8 * PROFILE_UP_FAC && co >= 0) { + console.log("profile down"); + profile.value = profs[co - 1] } } } -function profile_bw(p: EncodingProfile): number { - if (p.audio) return p.audio.bitrate / 8 - if (p.video) return p.video.bitrate / 8 - if (p.subtitles) return 100 - return 0 +function profile_bw(p?: EncodingProfile, fallback = 0): number { + if (p?.audio) return p.audio.bitrate / 8 + if (p?.video) return p.video.bitrate / 8 + if (p?.subtitles) return 100 + return fallback } diff --git a/web/script/player/track.ts b/web/script/player/track.ts index fe4c3c1..bcff607 100644 --- a/web/script/player/track.ts +++ b/web/script/player/track.ts @@ -3,7 +3,7 @@ import { JhlsTrack, TimeRange } from "./jhls.d.ts"; import { BufferRange, Player } from "./player.ts"; import { EncodingProfileExt } from "./profiles.ts"; -const TARGET_BUFFER_DURATION = 15 +const TARGET_BUFFER_DURATION = 5 const MIN_BUFFER_DURATION = 1 export interface AppendRange extends TimeRange { buf: ArrayBuffer, index: number, cb: () => void } @@ -79,7 +79,7 @@ export class PlayerTrack { async load(index: number) { this.loading.add(index) this.player.profile_selector.select_optimal_profile(this.track_index, this.profile) - const url = `/n/${encodeURIComponent(this.node_id)}/stream?format=hlsseg&tracks=${this.track_index}&index=${index}${this.profile.value ? `profile=${this.profile.value.id}` : ""}`; + const url = `/n/${encodeURIComponent(this.node_id)}/stream?format=hlsseg&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 }) @@ -91,6 +91,7 @@ export class PlayerTrack { if (this.append_queue.length) { const seg = this.append_queue[0]; this.source_buffer.timestampOffset = seg.start + // TODO why is pushing so unreliable?! sometimes it does not add it this.source_buffer.appendBuffer(seg.buf); this.append_queue.splice(0, 1) this.current_load = seg |