Custom Controls

Create a customized control interface for your video player

0:00 / 0:00

Code Example

tsx
1import { VideoPlayer, usePlayerState } from 'react-advanced-video-player';
2
3function CustomControls() {
4 const { playing, currentTime, duration, togglePlay } = usePlayerState();
5
6 return (
7 <div className="custom-controls">
8 <button onClick={togglePlay}>
9 {playing ? 'Pause' : 'Play'}
10 </button>
11 <div className="progress-bar">
12 <div
13 className="progress"
14 style={{ width: `${(currentTime / duration) * 100}%` }}
15 />
16 </div>
17 <span>{formatTime(currentTime)} / {formatTime(duration)}</span>
18 </div>
19 );
20}
21
22function App() {
23 return (
24 <VideoPlayer
25 src="https://example.com/video.mp4"
26 customControls={<CustomControls />}
27 />
28 );
29}

How it Works

Creating custom controls allows you to fully customize the look and functionality of your video player. The usePlayerState hook provides access to the player's state and methods.

The usePlayerState Hook

The usePlayerState hook provides the following values:

Property/MethodTypeDescription
playingbooleanWhether the video is currently playing
mutedbooleanWhether the video is muted
volumenumberCurrent volume level (0-1)
currentTimenumberCurrent playback position in seconds
durationnumberTotal duration of the video in seconds
bufferednumberAmount of the video that has been buffered in seconds
playbackRatenumberCurrent playback rate
togglePlay() => voidToggle between play and pause
toggleMute() => voidToggle between muted and unmuted
setVolume(volume: number) => voidSet the volume level (0-1)
seekTo(time: number) => voidSeek to a specific time in seconds
setPlaybackRate(rate: number) => voidSet the playback rate

Advanced Custom Controls

Here's a more advanced example with a complete set of custom controls:

tsx
1import { VideoPlayer, usePlayerState } from 'react-advanced-video-player';
2import { useState, useEffect, useRef } from 'react';
3
4function formatTime(seconds) {
5 const minutes = Math.floor(seconds / 60);
6 const secs = Math.floor(seconds % 60);
7 return `${minutes}:${secs < 10 ? '0' : ''}${secs}`;
8}
9
10function AdvancedCustomControls() {
11 const {
12 playing,
13 muted,
14 volume,
15 currentTime,
16 duration,
17 buffered,
18 playbackRate,
19 togglePlay,
20 toggleMute,
21 setVolume,
22 seekTo,
23 setPlaybackRate
24 } = usePlayerState();
25
26 const [showVolumeSlider, setShowVolumeSlider] = useState(false);
27 const [showSettings, setShowSettings] = useState(false);
28 const progressRef = useRef(null);
29
30 // Handle click on progress bar
31 const handleProgressClick = (e) => {
32 const rect = progressRef.current.getBoundingClientRect();
33 const pos = (e.clientX - rect.left) / rect.width;
34 seekTo(pos * duration);
35 };
36
37 return (
38 <div className="custom-controls">
39 {/* Progress bar */}
40 <div
41 ref={progressRef}
42 className="progress-container"
43 onClick={handleProgressClick}
44 >
45 <div
46 className="buffered-progress"
47 style={{ width: `${(buffered / duration) * 100}%` }}
48 />
49 <div
50 className="playback-progress"
51 style={{ width: `${(currentTime / duration) * 100}%` }}
52 />
53 </div>
54
55 <div className="controls-row">
56 {/* Play/Pause button */}
57 <button onClick={togglePlay}>
58 {playing ? <PauseIcon /> : <PlayIcon />}
59 </button>
60
61 {/* Volume controls */}
62 <div
63 className="volume-container"
64 onMouseEnter={() => setShowVolumeSlider(true)}
65 onMouseLeave={() => setShowVolumeSlider(false)}
66 >
67 <button onClick={toggleMute}>
68 {muted ? <VolumeMuteIcon /> : <VolumeIcon />}
69 </button>
70
71 {showVolumeSlider && (
72 <div className="volume-slider">
73 <input
74 type="range"
75 min="0"
76 max="1"
77 step="0.01"
78 value={muted ? 0 : volume}
79 onChange={(e) => setVolume(parseFloat(e.target.value))}
80 />
81 </div>
82 )}
83 </div>
84
85 {/* Time display */}
86 <div className="time-display">
87 {formatTime(currentTime)} / {formatTime(duration)}
88 </div>
89
90 {/* Spacer to push the following buttons to the right */}
91 <div className="spacer" />
92
93 {/* Playback rate */}
94 <div className="settings-container">
95 <button onClick={() => setShowSettings(!showSettings)}>
96 <SettingsIcon />
97 </button>
98
99 {showSettings && (
100 <div className="settings-menu">
101 <div className="playback-rates">
102 {[0.5, 1, 1.5, 2].map((rate) => (
103 <button
104 key={rate}
105 onClick={() => setPlaybackRate(rate)}
106 className={playbackRate === rate ? 'active' : ''}
107 >
108 {rate}x
109 </button>
110 ))}
111 </div>
112 </div>
113 )}
114 </div>
115
116 {/* Fullscreen button */}
117 <button onClick={() => {/* Handle fullscreen */}}>
118 <FullscreenIcon />
119 </button>
120 </div>
121 </div>
122 );
123}
124
125function App() {
126 return (
127 <VideoPlayer
128 src="https://example.com/video.mp4"
129 customControls={<AdvancedCustomControls />}
130 />
131 );
132}

This example demonstrates how to create a more advanced set of custom controls with:

  • A custom progress bar with buffering indicator
  • Volume control with hover effect
  • Playback rate selection
  • Time display
  • Fullscreen button