This example uses LiveSeekClient to subscribe to a live stream and scrub backward in that live feed without disconnecting.
LiveSeekClient is effectively a WHEP-based subscriber with additional live-seek behavior layered on top.
- Stream Manager based subscribe flow with
LiveSeekClient - live playback plus seek-back (DVR-style) capability during an active session
- selecting either a
baseURLorfullURLfor HLS recording access - HLS.js-assisted playback under the hood for recorded fragment seeking
This example is intended for Stream Manager deployments.
In code, the example enforces this requirement and blocks subscribe when Stream Manager is disabled.
For live seek to work, your deployment must include a VideoPackager node.
The VideoPackager is responsible for:
- recording/packaging live output
- making HLS artifacts available to storage/endpoints (for example CDN, S3, NFS)
- providing the recorded content source used by
baseURL/fullURL
Without this packaging path, there is no seekable HLS recording for LiveSeekClient to load.
At runtime, the client subscribes over WebRTC and also uses HLS playback data for time-shifted seeking.
In practice:
- WebRTC handles low-latency live playback.
- HLS.js handles fragment/manifest loading for seek-back playback.
- The SDK coordinates between live playback and recorded content access.
Enable live-seek by adding liveSeek to the LiveSeekClient init configuration.
{
enabled: <boolean>,
baseURL: <string | undefined>,
fullURL: <string | undefined>,
hlsjsRef: <hls.js reference | undefined>,
hlsElement: <HTMLVideoElement | undefined>,
options: <object | undefined>
}enabled: enables/disables live seek behavior.baseURL: optional base endpoint where HLS files are hosted.fullURL: optional full path to the target HLS manifest.hlsjsRef: optional HLS.js reference; if omitted, SDK checks globalwindow.Hls.hlsElement: optional target video element for HLS media attachment; SDK can manage this when omitted.options: optional HLS.js options (example default in this testbed:{ debug: true, backBufferLength: 0 }).
Example shape:
await subscriber.init({
endpoint,
streamName,
mediaElementId: 'subscriber-video',
connectionParams,
liveSeek: {
enabled: true,
baseURL,
fullURL,
options: { debug: true, backBufferLength: 0 },
},
})Use one or the other for HLS access:
baseURL: provide the parent location; SDK resolves the app/stream manifest path.fullURL: provide the exact.m3u8URL; SDK uses it directly.
Examples:
- base URL:
https://yourcdn/company - full URL:
https://yourcdn/company/live/stream1.m3u8
This example still subscribes through the WHEP endpoint resolution from Settings, but operationally it is documented and validated as Stream Manager-only due to VideoPackager and remote HLS workflow expectations.
const subscriber = new red5prosdk.LiveSeekClient()
await subscriber.init({
endpoint,
streamName,
mediaElementId: 'subscriber-video',
connectionParams,
liveSeek: {
enabled: true,
// choose one:
baseURL: 'https://yourcdn/company',
// fullURL: 'https://yourcdn/company/live/stream1.m3u8',
},
})
await subscriber.subscribe()When live seek is enabled, useful SDK events include:
WebRTC.LiveSeek.EnabledWebRTC.LiveSeek.DisabledWebRTC.LiveSeek.FragmentLoadingWebRTC.LiveSeek.FragmentLoaded
- subscribe setup +
liveSeekconfig:startSubscribe() - settings validation (Stream Manager requirement):
ensureCoreSettings() - URL mode handling (
baseURL/fullURL):resolveLiveSeekUrlValues() - HTML URL mode controls:
src/examples/whep-live-seek/index.html
Use this as the reference pattern for adding live time-shift playback on top of WHEP subscribe when packaged HLS recording is available.