Rewinding (DVR) while playing HLS¶
A current playlist segments are cached by a browser while playing HLS. This allows to rewind a stream back (a simple DVR function) in HLS player. Let's consider the DVR implementation based on VideoJS.
The following parameters should be set when creating a VideoJS player instance
const LIVE_THRESHOLD = 5;
const LIVE_TOLERANCE = 5;
...
const initVideoJsPlayer = function(video) {
let videoJsPlayer = videojs(video, {
...
liveui: true,
liveTracker: {
trackingThreshold: LIVE_THRESHOLD,
liveTolerance: LIVE_TOLERANCE
},
...
});
...
return videoJsPlayer;
}
Where:
liveui: true
- enables rewind interfaceliveTracker.trackingThreshold
- sets a minimal time in seconds to play before displaying rewind interfaceliveTracker.liveTolenrace
- sets how far from the seekable end should be considered live playback, in seconds
A maximum time to rewind back depend on a segments count in playlist and on a segment size. The parameters are set at server side
By default, the maximum time to rewind is 16 seconds
Playlist size should be increased to rewind a more time back
Segment size should not be changed because some browsers (Safari) may stop playing HLS segments of other size.
Use Player.currentTime()
method to rewind a currently playing stream. Get the maximum time range to rewind using Player.seekable()
method
const backBtnClick = function(event) {
if (player != null && player.liveTracker) {
...
let seekable = player.seekable();
let backTime = -1;
if (event.target.id.indexOf("10") !== -1) {
backTime = player.currentTime() - 10;
} else if (event.target.id.indexOf("30") !== -1) {
backTime = player.currentTime() - 30;
}
if (backTime < 0) {
backTime = seekable ? seekable.start(0) : player.currentTime();
}
player.currentTime(backTime);
}
}
Use Player.liveTracker.seekToLiveEdge()
to return back to live playback
const liveBtnClick = function() {
if (player != null && player.liveTracker) {
player.liveTracker.seekToLiveEdge();
...
}
}
Rewind interface may not be enabled for the first HLS subscriber, in this case the Player.liveTracker.seekToLiveEdge()
method should be called explicitly after some time since playback starts
const liveUIDisplay = function() {
stopLiveUITimer()
if (player && player.liveTracker) {
liveUITimer = setInterval(function() {
if (!player.liveTracker.isLive() && player.liveTracker.liveWindow() > LIVE_THRESHOLD) {
// Live UI is not displayed yet, seek to live edge to display
player.liveTracker.seekToLiveEdge();
}
}, LIVE_UI_INTERVAL)
}
}