go2rtc icon indicating copy to clipboard operation
go2rtc copied to clipboard

Buffering video for playback on poor connections

Open sanek11591 opened this issue 9 months ago • 4 comments

I have a device on openipc, it works via a cellular network, where the connection is extremely bad, I would like to accumulate a buffer for about a minute (selected by the user), then while this buffer is being read, load the video further (all this in the browser since go2rtc is installed on the device itself), so that the user can watch the video, albeit with a delay, but smoothly.

Is it possible to implement this for the MSE stream? For the HLS stream , I think this should be possible by increasing the number of segments, but why doesn't it work (h264 + aac)

sanek11591 avatar Apr 16 '25 12:04 sanek11591

You can do this by writing custom MSE viewer. Current viewer has 5 seconds buffer and 1 second delay: https://github.com/AlexxIT/go2rtc/blob/f45fef29d841e052e5625792b49581ec67b59f3e/www/video-rtc.js#L452-L466

AlexxIT avatar Apr 16 '25 13:04 AlexxIT

You can do this by writing custom MSE viewer. Current viewer has 5 seconds buffer and 1 second delay:

go2rtc/www/video-rtc.js

Lines 452 to 466 in f45fef2

if (!sb.updating && sb.buffered && sb.buffered.length) { const end = sb.buffered.end(sb.buffered.length - 1); const start = end - 5; const start0 = sb.buffered.start(0); if (start > start0) { sb.remove(start0, start); ms.setLiveSeekableRange(start, end); } if (this.video.currentTime < start) { this.video.currentTime = start; } const gap = end - this.video.currentTime; this.video.playbackRate = gap > 0.1 ? gap : 0.1; // console.debug('VideoRTC.buffered', gap, this.video.playbackRate, this.video.readyState); }

thank you i will try )

sanek11591 avatar Apr 16 '25 13:04 sanek11591

In case anyone stumbles across this issue, here is what has made my cameras behind a weak LTE connection much more pleasant to view:

                if (!sb.updating && sb.buffered && sb.buffered.length) {
                    const end = sb.buffered.end(sb.buffered.length - 1);
-                    const start = end - 5;
+                    const start = end - 20;
                    const start0 = sb.buffered.start(0);
                    if (start > start0) {
                        sb.remove(start0, start);
                        ms.setLiveSeekableRange(start, end);
                    }
                    if (this.video.currentTime < start) {
                        this.video.currentTime = start;
                    }
                    const gap = end - this.video.currentTime;
-                    this.video.playbackRate = gap > 0.1 ? gap : 0.1;
+                    this.video.playbackRate = gap > 2.0 ? 1.2 : 1.0;
                    // console.debug('VideoRTC.buffered', gap, this.video.playbackRate, this.video.readyState);
                }

b0ch3nski avatar Nov 23 '25 15:11 b0ch3nski

I think it needs to remove this logic or completely rewrite it.

AlexxIT avatar Nov 24 '25 14:11 AlexxIT