Hook
useYtcnPlayer
Core hook. Returns player refs, reactive state, and imperative controls.
Signature
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. |
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. |
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. |
Stale closure warning
YouTube API callbacks fire outside React
YouTube API callbacks fire outside React's render cycle. Do not read state directly inside YT callbacks — read refs instead. useYtcnPlayer handles this internally. If you extend the hook, follow the same ref-sync pattern.
stale-closure.ts
// ❌ WRONG — state.volume is stale inside YT callback
onReady: () => player.setVolume(state.volume)
// ✅ CORRECT — ref is always current
onReady: () => player.setVolume(volumeRef.current)