diff --git a/hls-player.js b/hls-player.js index c83deca..18f4f39 100644 --- a/hls-player.js +++ b/hls-player.js @@ -6,6 +6,7 @@ class PlaylistLoader { this.last_segment = null; this.refresh_interval = null; this.new_segments = []; + this.init_segment_uri = null; this.fetch_playlist(); } @@ -32,6 +33,8 @@ class PlaylistLoader { if (lines[i].startsWith("#")) { if (lines[i].startsWith("EXT-X-TARGETDURATION", 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 { if (segment_block_flag || lines[i] == '') { @@ -73,7 +76,10 @@ class VideoLoader { async prepare_buffer(_) { // fetch init.mp4 fragment and parse its mimetype // 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(); if (!MediaSource.isTypeSupported(mime)) { return; @@ -101,7 +107,7 @@ class VideoLoader { async resync_video() { 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. // not called on loop, only once on start if (buffer_end - this.player.currentTime > 15) { diff --git a/mp4-tree.js b/mp4-tree.js index 065d4b4..aca5f40 100644 --- a/mp4-tree.js +++ b/mp4-tree.js @@ -96,35 +96,36 @@ class MP4Tree { } parse_av01() { - this.parse_into('av01', 101); + this.parse_into('av01', 86); this.parse_into('av1C', 8); let tmp = this.data.getUint8(this.idx + 1); let profile = tmp >> 5; 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) { case 0: - let level_profile = "M"; + level_profile = "M"; break; case 1: - let level_profile = "H"; + level_profile = "H"; break; default: - let level_profile = ""; + level_profile = ""; } let depth_bits = (tmp >> 5) & 0x3; switch (depth_bits) { case 0: - let bit_depth = "8"; + bit_depth = "08"; break; case 1: - let bit_depth = "12"; + bit_depth = "12"; break; case 2: - let bit_depth = "10"; + bit_depth = "10"; break; default: - let bit_depth = "0"; + bit_depth = "0"; break; } this.codecs.push(["av01", profile, level.toString().padStart(2, "0") + level_profile, bit_depth].join('.'))