Initial commit: modern React video player library

Add all source files for a feature-rich, reusable video player built with React, TypeScript, and Vite. Includes core components, context, hooks, utilities, styles, demo app, and configuration files.
This commit is contained in:
hibna
2025-10-29 07:49:06 +03:00
parent d68df70124
commit b57b24d051
47 changed files with 4414 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
import { useEffect } from 'react'
import { usePlayerContext } from '../contexts/PlayerContext'
export const useKeyboardShortcuts = (enabled: boolean = true) => {
const {
videoState,
togglePlay,
seek,
setVolume,
toggleMute,
toggleFullscreen,
togglePictureInPicture,
} = usePlayerContext()
useEffect(() => {
if (!enabled) return
const handleKeyDown = (e: KeyboardEvent) => {
// Don't trigger if user is typing in an input
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
return
}
switch (e.key.toLowerCase()) {
case ' ':
case 'k':
e.preventDefault()
togglePlay()
break
case 'arrowleft':
e.preventDefault()
seek(Math.max(0, videoState.currentTime - 5))
break
case 'arrowright':
e.preventDefault()
seek(Math.min(videoState.duration, videoState.currentTime + 5))
break
case 'j':
e.preventDefault()
seek(Math.max(0, videoState.currentTime - 10))
break
case 'l':
e.preventDefault()
seek(Math.min(videoState.duration, videoState.currentTime + 10))
break
case 'arrowup':
e.preventDefault()
setVolume(Math.min(1, videoState.volume + 0.1))
break
case 'arrowdown':
e.preventDefault()
setVolume(Math.max(0, videoState.volume - 0.1))
break
case 'm':
e.preventDefault()
toggleMute()
break
case 'f':
e.preventDefault()
toggleFullscreen()
break
case 'p':
e.preventDefault()
togglePictureInPicture()
break
case '0':
case 'home':
e.preventDefault()
seek(0)
break
case 'end':
e.preventDefault()
seek(videoState.duration)
break
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
e.preventDefault()
const percent = parseInt(e.key) / 10
seek(videoState.duration * percent)
break
default:
break
}
}
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [
enabled,
videoState.currentTime,
videoState.duration,
videoState.volume,
togglePlay,
seek,
setVolume,
toggleMute,
toggleFullscreen,
togglePictureInPicture,
])
}