Live
A live pill, a jump back to the edge, and a timeline when the stream keeps a window to scrub through.
import { live } from "react-video-kit/live";Adds 609 B to a player1.6 KB on its ownSource
Adds a LIVE pill to the control bar. Press play below. This stream keeps about 20 seconds, so there's no timeline, only the pill.
"use client";import { hls } from "react-video-kit/hls";import { live } from "react-video-kit/live";import { defaultPlugins, VideoPlayer } from "react-video-kit/player";export default function Live() { return <VideoPlayer src="/live/stream.m3u8" plugins={[hls(), live(), ...defaultPlugins()]} load="visible" />;}Usage
live() doesn't play anything itself, so it goes with hls or dash:
import { hls } from "react-video-kit/hls";import { live } from "react-video-kit/live";import { defaultPlugins, VideoPlayer } from "react-video-kit/player";const plugins = [hls(), live(), ...defaultPlugins()];<VideoPlayer src="/stream.m3u8" plugins={plugins} />;It's safe to keep for on-demand video, where it shows nothing.
edgeTolerance sets how many seconds behind the edge still counts as live. It defaults to 6:
live({ edgeTolerance: 10 });Plain live and DVR
A stream that keeps at least 60 seconds counts as DVR, and the viewer can scrub back through what it keeps. Anything shorter isn't worth a scrubber, so it's plain live. This stream keeps about 100 seconds. Click back along the timeline, then press the pill to return.
"use client";import { hls } from "react-video-kit/hls";import { live } from "react-video-kit/live";import { defaultPlugins, VideoPlayer } from "react-video-kit/player";export default function LiveDvr() { return <VideoPlayer src="/live/dvr.m3u8" plugins={[hls(), live(), ...defaultPlugins()]} load="visible" />;}| Control | Plain live | DVR |
|---|---|---|
| Window | Under 60 seconds | 60 seconds or more |
| Timeline | Hidden | Shown, and it follows the edge |
| Speed menu | Hidden | Shown |
| Elapsed time | Hidden | Hidden |
media.timeline.kind | "live" | "dvr" |
media.capabilities.seek and rate | false | true |
| Attributes on the root | data-live | data-live, data-dvr |
The window comes from hls.js's playlist duration, dash.js's DVR window, or the element's seekable range under native HLS.
What the viewer sees
- The pill reads LIVE, with a coloured dot (
--rv-live) while playback is running and withinedgeToleranceof the edge. - When the viewer pauses or falls further behind, the dot and the text dim, and the pill's accessible name changes to "Go to live".
- Pressing the pill jumps to the edge, and plays if paused.
Build your own control
useCommands gives you goLive, and useVideoState tells you when it's worth offering:
"use client";import { useCommands, useVideoState } from "react-video-kit";import { live } from "react-video-kit/live";function BackToLive() { const behind = useVideoState(live, (state) => state.active && !state.atEdge); const { goLive } = useCommands(live); return behind ? <button onClick={() => goLive()}>Back to live</button> : null;}LiveIndicator is the pill. When you compose your own layout, place it anywhere inside the player:
import * as Video from "react-video-kit";import { LiveIndicator } from "react-video-kit/live";<Video.ControlRow> <LiveIndicator /></Video.ControlRow>;Behaviour
- hls.js and dash.js report live state on their own. Without
live(), the stream still plays and the root still getsdata-live, but there's no pill, nogoLive, and nodata-dvr, so the default skin hides the timeline even on a DVR stream. - Under native HLS,
live()is what recognises the stream: it reads the window from the element. goLiveseeks tomedia.live.edge. For hls.js that's itsliveSyncPositionwhen it has one, and otherwise the end of the playlist.data-live-edgeon the root only looks at position, while the pill'sdata-edgealso needs playback to be running.- On plain live,
capabilities.seekandcapabilities.rateare false, so the seek and speed keys in the hotkeys plugin and the double tap in the gestures plugin and the system's seek buttons in the Media Session plugin do nothing.seekandsetRatestill work from your own code, which is howgoLivereaches the edge. media.liveholdsdvr,start,edge, andlatency, for anything you want to build around them.latencyis0under native HLS.
API
Options
| Option | Type | Description |
|---|---|---|
| edgeTolerance? | number | How many seconds behind the edge still counts as live. |
State
Read it with useVideoState(live, (state) => …).
| Field | Type | Description |
|---|---|---|
| active | boolean | True while the current source is live. |
| dvr | boolean | True when the viewer can seek back through a window of the stream. |
| atEdge | boolean | True within edgeTolerance seconds of the live edge, and when the source isn't live. |
Commands
Call them with useCommands(live).
| Command | Type | Description |
|---|---|---|
| goLive | () => void | Jumps to the live edge, and plays if paused. |
Parts
| Part | Description |
|---|---|
| LiveIndicator | Says when playback is live, and returns there when it isn't. Hidden otherwise. |