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.

tsx
const paused = useVideoState((media) => media.paused);

Pass a plugin first to read its state too, with its types inferred:

tsx
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:

tsx
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.

tsx
const { play, seek, setVolume } = useCommands();const { toggle } = useCommands(fullscreen);
FieldTypeDescription
play() => Promise<boolean>Resolves to whether playback started. Never rejects.
pause() => voidPauses playback, unless a lock blocks it.
seek(time: number) => voidMoves to time in seconds, kept within the timeline.
scrub(active: boolean) => voidHolds playback while the viewer drags the timeline, then restores it.
setVolume(volume: number) => voidSets the volume, keeping it between 0 and 1.
setMuted(muted: boolean) => voidMutes or unmutes, leaving the volume as it is.
setRate(rate: number) => voidSets the playback speed, ignoring anything that isn't above 0.
setQuality(id: string | "auto") => voidSwitches to this level, or to automatic choice with auto if the provider offers it.
setAudioTrack(id: string) => voidSwitches to the audio track with this id.
setTextTrack(id: string | null) => voidTells the provider which text track to use, or none with null.
setSource(source: SourceInput | null) => voidChanges what plays, or clears it with null.
reload(startTime?: number) => voidLoads 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.

tsx
"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.

tsx
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.

tsx
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.

tsx
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.

tsx
"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