Hooks
Read state, call commands, and follow time from any component inside the player.
All of these work inside Root or VideoPlayer, and are exported from both react-video-kit and react-video-kit/primitives. Outside the player, use a ref.
useVideoState
Subscribes to a value, and re-renders only when that value changes.
const paused = useVideoState((media) => media.paused);Pass a plugin first to read its state too, with its types inferred:
import { fullscreen } from "react-video-kit/fullscreen";const active = useVideoState(fullscreen, (state) => state.active);A selector that builds a new object each time needs an equality check, or it would re-render on every change to any state. shallow covers most cases:
import { shallow, useVideoState } from "react-video-kit";const { volume, muted } = useVideoState((media) => ({ volume: media.volume, muted: media.muted }), shallow);Current time isn't in this state. See useClock and useCurrentTime.
Subscribes to a plugin's state, typed from the plugin factory. Subscribes to kernel media state, re-rendering only when the result changes.
{ <Factory extends AnyPluginFactory, Value>(plugin: Factory, select: (state: StateOf<Factory>, media: MediaState) => Value, isEqual?: Equality<Value>): Value; <Value>(select: (media: MediaState) => Value, isEqual?: Equality<Value>): Value; }useCommands
Returns the core commands, or a plugin's commands when given its factory. Calling it never causes a render.
const { play, seek, setVolume } = useCommands();const { toggle } = useCommands(fullscreen);| Field | Type | Description |
|---|---|---|
| play | () => Promise<boolean> | Resolves to whether playback started. Never rejects. |
| pause | () => void | Pauses playback, unless a lock blocks it. |
| seek | (time: number) => void | Moves to time in seconds, kept within the timeline. |
| scrub | (active: boolean) => void | Holds playback while the viewer drags the timeline, then restores it. |
| setVolume | (volume: number) => void | Sets the volume, keeping it between 0 and 1. |
| setMuted | (muted: boolean) => void | Mutes or unmutes, leaving the volume as it is. |
| setRate | (rate: number) => void | Sets the playback speed, ignoring anything that isn't above 0. |
| setQuality | (id: string | "auto") => void | Switches to this level, or to automatic choice with auto if the provider offers it. |
| setAudioTrack | (id: string) => void | Switches to the audio track with this id. |
| setTextTrack | (id: string | null) => void | Tells the provider which text track to use, or none with null. |
| setSource | (source: SourceInput | null) => void | Changes what plays, or clears it with null. |
| reload | (startTime?: number) => void | Loads the current source again, optionally resuming from startTime. After a failure it picks up where that interrupted, and plays if the viewer was watching. |
useClock
Calls a function as playback advances, with no render. Use this for anything that moves.
"use client";import { useCallback, useRef } from "react";import { useClock, useVideoState } from "react-video-kit";function Progress() { const bar = useRef<HTMLDivElement>(null); const duration = useVideoState((media) => media.duration); const write = useCallback( (time: number) => { if (bar.current && duration) bar.current.style.transform = `scaleX(${time / duration})`; }, [duration] ); const resolution = useCallback(() => duration / 1000, [duration]); useClock(write, resolution); return <div ref={bar} className="h-1 origin-left bg-white" />;}resolution returns how many seconds must pass before an update is visible. It's a function so that it can depend on something that changes, such as the element's width. Both arguments should be stable, so wrap them in useCallback.
Runs write as playback advances, without rendering. Use this for anything that follows time: fills, thumbs, and text written straight to the DOM.
(write: (time: number) => void, resolution: () => number) => void
useCurrentTime
Time as React state. It renders once per resolution seconds, with a default of 1. It's simpler than useClock, and good for text and conditions.
const time = useCurrentTime();return time < 10 ? <p>Welcome back</p> : null;Time as React state, for text. Renders once per resolution seconds.
(resolution?: number) => number
usePlayer
Returns the Player, for whatever the other hooks don't cover. It never causes a render.
const player = usePlayer();const position = player.clock.time();const element = player.video();() => Player
useLabel
Returns a translated string from the i18n plugin when it's installed, or your fallback when it isn't. Use it for text in your own controls.
const label = useLabel("settings", "Settings");A localized string from the i18n plugin when it's installed, else fallback.
(key: string, fallback: string) => string
useTimelinePreview
Calls your function with the time under the pointer, or null when there is none. It works inside Timeline, and it's how thumbnails follows the pointer without rendering.
"use client";import { useRef } from "react";import { useTimelinePreview } from "react-video-kit";function PreviewLabel() { const element = useRef<HTMLSpanElement>(null); useTimelinePreview((time) => { if (element.current) element.current.textContent = time === null ? "" : `${Math.round(time)}s`; }); return <span ref={element} />;}Calls listener with the time under the pointer, or null when there is none.
(listener: PreviewListener) => void