properly working with fmp4 and av1

This commit is contained in:
Muaz Ahmad 2023-10-26 00:19:40 +05:00
parent fd6867bc57
commit 6cbf623adc
2 changed files with 18 additions and 11 deletions

View file

@ -6,6 +6,7 @@ class PlaylistLoader {
this.last_segment = null; this.last_segment = null;
this.refresh_interval = null; this.refresh_interval = null;
this.new_segments = []; this.new_segments = [];
this.init_segment_uri = null;
this.fetch_playlist(); this.fetch_playlist();
} }
@ -32,6 +33,8 @@ class PlaylistLoader {
if (lines[i].startsWith("#")) { if (lines[i].startsWith("#")) {
if (lines[i].startsWith("EXT-X-TARGETDURATION", 1)) { if (lines[i].startsWith("EXT-X-TARGETDURATION", 1)) {
this.refresh_interval = parseFloat(lines[i].split(':')[1]); this.refresh_interval = parseFloat(lines[i].split(':')[1]);
} else if (lines[i].startsWith("EXT-X-MAP:URI", 1)) {
this.init_segment_uri = lines[i].split('=')[1].slice(1, -1);
} }
} else { } else {
if (segment_block_flag || lines[i] == '') { if (segment_block_flag || lines[i] == '') {
@ -73,7 +76,10 @@ class VideoLoader {
async prepare_buffer(_) { async prepare_buffer(_) {
// fetch init.mp4 fragment and parse its mimetype // fetch init.mp4 fragment and parse its mimetype
// codec info is needed for MediaSource compat // codec info is needed for MediaSource compat
let init_frag = await this.fetch_video('/vid/' + this.stream_key + '/init.mp4'); while (this.playlist_loader.init_segment_uri === null) {
await new Promise(r => setTimeout(r, 250));
}
let init_frag = await this.fetch_video(this.playlist_loader.init_segment_uri);
let mime = (new MP4Tree(init_frag)).get_mime(); let mime = (new MP4Tree(init_frag)).get_mime();
if (!MediaSource.isTypeSupported(mime)) { if (!MediaSource.isTypeSupported(mime)) {
return; return;
@ -101,7 +107,7 @@ class VideoLoader {
async resync_video() { async resync_video() {
if (!this.media_buffer.updating) { if (!this.media_buffer.updating) {
const buffer_end = this.media_buffer.buffered.end(0); let buffer_end = this.media_buffer.buffered.end(0);
// if video is over 15s behind, seek to 5s behind current end. // if video is over 15s behind, seek to 5s behind current end.
// not called on loop, only once on start // not called on loop, only once on start
if (buffer_end - this.player.currentTime > 15) { if (buffer_end - this.player.currentTime > 15) {

View file

@ -96,35 +96,36 @@ class MP4Tree {
} }
parse_av01() { parse_av01() {
this.parse_into('av01', 101); this.parse_into('av01', 86);
this.parse_into('av1C', 8); this.parse_into('av1C', 8);
let tmp = this.data.getUint8(this.idx + 1); let tmp = this.data.getUint8(this.idx + 1);
let profile = tmp >> 5; let profile = tmp >> 5;
let level = tmp & 0x1f; let level = tmp & 0x1f;
let tmp = this.data.getUint8(this.idx + 2); let level_profile, bit_depth;
tmp = this.data.getUint8(this.idx + 2);
switch (tmp >> 7) { switch (tmp >> 7) {
case 0: case 0:
let level_profile = "M"; level_profile = "M";
break; break;
case 1: case 1:
let level_profile = "H"; level_profile = "H";
break; break;
default: default:
let level_profile = ""; level_profile = "";
} }
let depth_bits = (tmp >> 5) & 0x3; let depth_bits = (tmp >> 5) & 0x3;
switch (depth_bits) { switch (depth_bits) {
case 0: case 0:
let bit_depth = "8"; bit_depth = "08";
break; break;
case 1: case 1:
let bit_depth = "12"; bit_depth = "12";
break; break;
case 2: case 2:
let bit_depth = "10"; bit_depth = "10";
break; break;
default: default:
let bit_depth = "0"; bit_depth = "0";
break; break;
} }
this.codecs.push(["av01", profile, level.toString().padStart(2, "0") + level_profile, bit_depth].join('.')) this.codecs.push(["av01", profile, level.toString().padStart(2, "0") + level_profile, bit_depth].join('.'))