Build custom video players effortless
- Render props, get all video state passed down as props.
- Bidirectional flow to render and update the video state in a declarative way.
- No side effects out of the box, you just need to build the UI.
- Actions handling: play, pause, mute, unmute, navigate, etc
- Dependency free, <2KB size
- Cross-browser support, no more browser hacks.
https://zzarcon.github.io/react-video-renderer
yarn add react-video-rendererRender video state and communicate user interactions up when volume or time changes.
import Video from 'react-video-renderer'; <Video src="https://mysite.com/video.mp4"> {(video, state, actions) => ( <div> {video} <div>{state.currentTime} / {state.duration} / {state.buffered}</div> <progress value={state.currentTime} max={state.duration} onChange={actions.navigate} /> <progress value={state.volume} max={1} onChange={actions.setVolume} /> <button onClick={actions.play}>Play</button> <button onClick={actions.pause}>Pause</button> <button onClick={actions.requestFullScreen}>Fullscreen</button> </div> )} </Video>interface Props { src: string; children: RenderCallback; controls?: boolean; autoPlay?: boolean; preload?: string; textTracks?: VideoTextTracks; }type RenderCallback = (reactElement: ReactElement<HTMLMediaElement>, state: VideoState, actions: VideoActions, ref: React.RefObject<HTMLMediaElement>) => ReactNode;interface VideoState { status: 'playing' | 'paused' | 'errored'; currentTime: number; currentActiveCues: (kind: VideoTextTrackKind, lang: string) => TextTrackCueList | null | undefined; volume: number; duration: number; buffered: number; isMuted: boolean; isLoading: boolean; error?: MediaError | null; }interface VideoActions { play: () => void; pause: () => void; navigate: (time: number) => void; setVolume: (volume: number) => void; requestFullscreen: () => void; mute: () => void; unmute: () => void; toggleMute: () => void; }this is all you need to detect video errors
<Video src="some-error-video.mov"> {(video, state) => { if (state.status === 'errored') { return ( <ErrorWrapper> Error </ErrorWrapper> ); } return ( <div> {video} </div> ) }} </Video>you can still interact with the player regardless if the video is loading or not
<Video src="my-video.mp4"> {(video, state, actions) => { const loadingComponent = state.isLoading ? 'loading...' : undefined; return ( <div> {video} {loadingComponent} <button onClick={actions.play}>Play</button> <button onClick={actions.pause}>Pause</button> </div> ) }} </Video>HTML5 text tracks support for videos.
subtitles can be rendered natively, or they can be rendered using
VideoState.currentActiveCuesproperty:
<Video src="my-video.mp4" textTracks={{ 'subtitles': { selectedTrackIndex: 0, tracks: [ { src: 'subtitles-en.vtt', lang: 'en', label: 'Subtitles (english)' }, { src: 'subtitles-es.vtt', lang: 'es', label: 'Subtitles (spanish)' }, ] } }} > {(video, state, actions) => { const cues = state.currentActiveCues('subtitles', 'en'); const subtitles = cue && cue.length > 0 ? ( <div> {Array.prototype.map.call(cues, (cue, i) => <span key={i}>{cue.text}</span>)} </div> ) : undefined; return ( <div> {video} {subtitles} <button onClick={actions.play}>Play</button> <button onClick={actions.pause}>Pause</button> </div> ) }} </Video>