aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/config.rs8
-rw-r--r--stream/src/segment.rs2
-rw-r--r--web/script/player/mod.ts6
-rw-r--r--web/script/player/profiles.ts29
-rw-r--r--web/script/player/track.ts5
5 files changed, 34 insertions, 16 deletions
diff --git a/common/src/config.rs b/common/src/config.rs
index 2666d17..65d7326 100644
--- a/common/src/config.rs
+++ b/common/src/config.rs
@@ -69,9 +69,15 @@ mod default {
EncodingProfile::Video {
codec: "libsvtav1".to_string(),
preset: 8,
- bitrate: 1_500_000,
+ bitrate: 1_200_000,
width: 1280,
},
+ EncodingProfile::Video {
+ codec: "libsvtav1".to_string(),
+ preset: 8,
+ bitrate: 300_000,
+ width: 640,
+ },
EncodingProfile::Audio {
codec: "libopus".to_string(),
bitrate: 128_000,
diff --git a/stream/src/segment.rs b/stream/src/segment.rs
index 51674d7..ce3f8e1 100644
--- a/stream/src/segment.rs
+++ b/stream/src/segment.rs
@@ -25,7 +25,7 @@ pub async fn segment_stream(
if let Some(profile) = spec.profile {
let location = transcode(
- "",
+ &format!("{track} {n} {:?}", node.private.source), // TODO maybe not use the entire source
CONF.transcoding_profiles
.get(profile)
.ok_or(anyhow!("profile out of range"))?,
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