properly working with fmp4 and av1
This commit is contained in:
parent
fd6867bc57
commit
6cbf623adc
2 changed files with 18 additions and 11 deletions
|
@ -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) {
|
||||||
|
|
19
mp4-tree.js
19
mp4-tree.js
|
@ -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('.'))
|
||||||
|
|
Loading…
Reference in a new issue