From 822b84b3bc55df868393f46cdd78de3225ef6234 Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Thu, 24 Aug 2023 12:53:22 +0500 Subject: [PATCH] playlist early stop, old segment deletion + resyncing + async fixes --- hls-player.js | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/hls-player.js b/hls-player.js index 5d5faab..fff6863 100644 --- a/hls-player.js +++ b/hls-player.js @@ -9,8 +9,10 @@ class PlaylistLoader { async fetch_playlist() { const response = await fetch(this.playlist_src); - this.parse_playlist(await response.text()); - setTimeout(this.fetch_playlist.bind(this), this.refresh_interval * 1000); + if (response.status == 200) { + this.parse_playlist(await response.text()); + setTimeout(this.fetch_playlist.bind(this), this.refresh_interval * 1000); + } } parse_playlist(playlist_content) { @@ -58,14 +60,38 @@ class VideoLoader { this.media_buffer = this.media_source.addSourceBuffer(mime); this.media_buffer.mode = 'segments'; this.media_buffer.appendBuffer(init_frag); - this.fetch_new_segments(); + await this.fetch_new_segments(); + this.resync_video(); + this.cleanup_old(); + } + + async cleanup_old() { + let timeout = 60000; + if (!this.media_buffer.updating) { + this.media_buffer.remove(0, this.media_buffer.buffered.end(0) - 10); + } else { + timeout = 250; + } + setTimeout(this.cleanup_old.bind(this), timeout); + } + + async resync_video() { + if (!this.media_buffer.updating) { + const buffer_end = this.media_buffer.buffered.end(0); + if (buffer_end - this.player.currentTime > 15) { + this.player.currentTime = buffer_end - 5; + } + } } async fetch_new_segments() { while (this.playlist_loader.new_segments.length > 0) { - let segment_uri = this.playlist_loader.new_segments.shift(); - let segment_stream = await this.fetch_video(segment_uri); - this.media_buffer.appendBuffer(segment_stream); + if (!this.media_buffer.updating) { + let segment_uri = this.playlist_loader.new_segments.shift(); + let segment_stream = await this.fetch_video(segment_uri); + this.media_buffer.appendBuffer(segment_stream); + } + await new Promise(r => setTimeout(r, 250)); } setTimeout(this.fetch_new_segments.bind(this), this.playlist_loader.refresh_interval * 1000); }