useYtcnPlayer
Core hook. Returns player refs, reactive state, and imperative controls.
Signature
const { containerRef, playerDivRef, state, controls } =
useYtcnPlayer(options)Options
| Prop | Type | Default | Description |
|---|---|---|---|
| videoId* | string | — | YouTube video ID to load. |
| startAt | number | 0 | Initial playback position in seconds. |
| onEnd | () => void | — | Called when the video finishes playing. |
| onTimeUpdate | (current: number, duration: number) => void | — | Called every 250ms during playback with current time and total duration. |
| keyboardShortcuts | boolean | true | Enable built-in keyboard shortcut handling. |
YouTube video ID to load.
Initial playback position in seconds.
Called when the video finishes playing.
Called every 250ms during playback with current time and total duration.
Enable built-in keyboard shortcut handling.
Returns — State
The state object is reactive — it re-renders your component when any field changes.
| Prop | Type | Default | Description |
|---|---|---|---|
| phase | "thumbnail" | "loading" | "ready" | — | Current player lifecycle phase. Thumbnail is shown first, then loading while iframe initializes, then ready when playback begins. |
| isPlaying | boolean | — | Whether the video is currently playing. |
| isMuted | boolean | — | Whether the video is currently muted. |
| volume | number | — | Current volume level from 0 to 100. |
| currentTime | number | — | Current playback position in seconds. Polled every 250ms. |
| duration | number | — | Total video duration in seconds. |
| loadedFraction | number | — | Buffer progress from 0 to 1. |
| isLoading | boolean | — | True while the player is initializing. |
| isFullscreen | boolean | — | True when in fullscreen mode. |
| playbackRate | 0.75 | 1 | 1.5 | 2 | — | Currently active playback speed. |
Current player lifecycle phase. Thumbnail is shown first, then loading while iframe initializes, then ready when playback begins.
Whether the video is currently playing.
Whether the video is currently muted.
Current volume level from 0 to 100.
Current playback position in seconds. Polled every 250ms.
Total video duration in seconds.
Buffer progress from 0 to 1.
True while the player is initializing.
True when in fullscreen mode.
Currently active playback speed.
Returns — Controls
| Prop | Type | Default | Description |
|---|---|---|---|
| togglePlay() | () => void | — | Play or pause the video. |
| seekTo(seconds) | (s: number) => void | — | Jump to an absolute position in seconds. |
| seekRelative(delta) | (d: number) => void | — | Seek ±N seconds from current position. |
| setVolume(0–100) | (v: number) => void | — | Set volume level. Also unmutes if muted. |
| toggleMute() | () => void | — | Toggle mute state. |
| setSpeed(speed) | (s: PlaybackSpeed) => void | — | Set playback rate to 0.75, 1, 1.5, or 2. |
| toggleFullscreen() | () => void | — | Enter or exit fullscreen mode. |
Play or pause the video.
Jump to an absolute position in seconds.
Seek ±N seconds from current position.
Set volume level. Also unmutes if muted.
Toggle mute state.
Set playback rate to 0.75, 1, 1.5, or 2.
Enter or exit fullscreen mode.
Stale closure warning
YouTube API callbacks fire outside React
// ❌ WRONG — state.volume is stale inside YT callback
onReady: () => player.setVolume(state.volume)
// ✅ CORRECT — ref is always current
onReady: () => player.setVolume(volumeRef.current)