aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-10-02 22:58:44 +0200
committermetamuffin <metamuffin@disroot.org>2023-10-02 22:58:44 +0200
commit1f11c16aefe71d68605d2cd0ad5da9c016aa3570 (patch)
tree39a5cdc211c6f5da660acb4a8da36e88f88863c7
parente52890060edb988cf16f184d5711e539b1c1dd01 (diff)
downloadjellything-1f11c16aefe71d68605d2cd0ad5da9c016aa3570.tar
jellything-1f11c16aefe71d68605d2cd0ad5da9c016aa3570.tar.bz2
jellything-1f11c16aefe71d68605d2cd0ad5da9c016aa3570.tar.zst
testing profile autoselect
-rw-r--r--web/script/player/download.ts3
-rw-r--r--web/script/player/mod.ts4
-rw-r--r--web/script/player/player.ts6
-rw-r--r--web/script/player/profiles.ts38
-rw-r--r--web/script/player/track.ts4
5 files changed, 41 insertions, 14 deletions
diff --git a/web/script/player/download.ts b/web/script/player/download.ts
index 63085b8..86a899f 100644
--- a/web/script/player/download.ts
+++ b/web/script/player/download.ts
@@ -22,7 +22,6 @@ export class SegmentDownloader {
duration: (dl_body - dl_header) / 1000,
size: buf.byteLength
}
- console.log(m);
this.measurements.push(m)
this.update_bandwidth()
}
@@ -35,8 +34,6 @@ export class SegmentDownloader {
const total_size = this.measurements.reduce((a, v) => v.size + a, 0)
const total_duration = this.measurements.reduce((a, v) => v.duration + a, 0)
const average = total_size / total_duration
- console.log(total_size, average, this.measurements);
-
this.bandwidth.value = average
}
}
diff --git a/web/script/player/mod.ts b/web/script/player/mod.ts
index 9c1b060..89919e4 100644
--- a/web/script/player/mod.ts
+++ b/web/script/player/mod.ts
@@ -22,7 +22,7 @@ function initialize_player(el: HTMLElement, node_id: string) {
el.innerHTML = "" // clear the body
const player = new Player(node_id)
- const show_stats = new OVar(false);
+ const show_stats = new OVar(true);
const toggle_playing = () => player.playing.value ? player.pause() : player.play()
const pri_map = (v: number) => (v / player.duration.value * 100) + "%"
@@ -123,7 +123,7 @@ 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.video) return `codec=${profile.video.codec} vw=${show.metric(profile.video.width ?? -1, "Hz")} vbr=${show.metric(profile.video.bitrate, "b/s")} preset=${profile.video.preset}`
+ 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/player.ts b/web/script/player/player.ts
index 08975b2..f3a1f6e 100644
--- a/web/script/player/player.ts
+++ b/web/script/player/player.ts
@@ -2,6 +2,7 @@ import { OVar, e } from "../jshelper/mod.ts";
import { JhlsMetadata, TimeRange } from "./jhls.d.ts";
import { SegmentDownloader } from "./download.ts";
import { PlayerTrack } from "./track.ts";
+import { ProfileSelector } from "./profiles.ts";
export interface BufferRange extends TimeRange { status: "buffered" | "loading" | "queued" }
export class Player {
@@ -9,6 +10,7 @@ export class Player {
public media_source = new MediaSource();
public tracks = new OVar<PlayerTrack[]>([]);
public downloader: SegmentDownloader = new SegmentDownloader();
+ public profile_selector!: ProfileSelector
public position = new OVar(0)
public duration = new OVar(1)
@@ -63,10 +65,12 @@ export class Player {
const res = await fetch(`/n/${encodeURIComponent(this.node_id)}/stream?format=jhls`)
if (!res.ok) return this.error.value = "Cannot download JHLS metadata"
const metadata = await res.json() as JhlsMetadata
- this.buffering_status.value = undefined
+ this.buffering_status.value = undefined
this.duration.value = metadata.duration
this.video.src = URL.createObjectURL(this.media_source)
+ this.profile_selector = new ProfileSelector(this.downloader.bandwidth, metadata)
+
this.media_source.addEventListener("sourceopen", async () => {
this.tracks.value.push(new PlayerTrack(this, this.node_id, 0, metadata.tracks[0]))
this.tracks.value.push(new PlayerTrack(this, this.node_id, 1, metadata.tracks[1]))
diff --git a/web/script/player/profiles.ts b/web/script/player/profiles.ts
index 3b3379a..b4de534 100644
--- a/web/script/player/profiles.ts
+++ b/web/script/player/profiles.ts
@@ -1,22 +1,46 @@
import { OVar } from "../jshelper/mod.ts";
import { EncodingProfile, JhlsMetadata } from "./jhls.d.ts";
-export interface EncodingProfileExt extends EncodingProfile { id: number }
+export interface EncodingProfileExt extends EncodingProfile { id: number, order: number }
export class ProfileSelector {
profiles_video: EncodingProfileExt[] = []
profiles_audio: EncodingProfileExt[] = []
profiles_subtitles: EncodingProfileExt[] = []
+ remux_bandwidth = new Map<number, { size: number, duration: number }>()
constructor(private bandwidth: OVar<number>, private metadata: JhlsMetadata) {
for (let id = 0; id < metadata.extra_profiles.length; id++) {
const p = metadata.extra_profiles[id];
- if (p.audio) this.profiles_audio.push({ id, ...p })
- if (p.video) this.profiles_video.push({ id, ...p })
- if (p.subtitles) this.profiles_subtitles.push({ id, ...p })
+ if (p.audio) this.profiles_audio.push({ id, order: 0, ...p })
+ if (p.video) this.profiles_video.push({ id, order: 0, ...p })
+ if (p.subtitles) this.profiles_subtitles.push({ id, order: 0, ...p })
}
+ this.profiles_audio.sort((a, b) => profile_bw(b) - profile_bw(a))
+ this.profiles_video.sort((a, b) => profile_bw(b) - profile_bw(a))
+ this.profiles_subtitles.sort((a, b) => profile_bw(b) - profile_bw(a))
+ for (let i = 0; i < this.profiles_audio.length; i++) this.profiles_audio[i].order = i
+ for (let i = 0; i < this.profiles_video.length; i++) this.profiles_video[i].order = i
+ for (let i = 0; i < this.profiles_subtitles.length; i++) this.profiles_subtitles[i].order = i
}
-
- select_optimal_profile(track: number, profile: OVar<EncodingProfileExt>) {
- // TODO
+ profile_list_for_track(track: number): EncodingProfileExt[] {
+ const i = this.metadata.tracks[track].info.kind
+ if (i.audio) return this.profiles_audio
+ if (i.video) return this.profiles_video
+ if (i.subtitles) return this.profiles_subtitles
+ 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
+ }
}
}
+
+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
+}
diff --git a/web/script/player/track.ts b/web/script/player/track.ts
index 59690c3..fe4c3c1 100644
--- a/web/script/player/track.ts
+++ b/web/script/player/track.ts
@@ -78,7 +78,9 @@ export class PlayerTrack {
async load(index: number) {
this.loading.add(index)
- const buf = await this.player.downloader.download(`/n/${encodeURIComponent(this.node_id)}/stream?format=hlsseg&tracks=${this.track_index}&index=${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 buf = await this.player.downloader.download(url)
await new Promise<void>(cb => {
this.append_queue.push({ buf, ...this.metadata.segments[index], index, cb })
this.tick_append()