--- name: video-producer description: Expert in video playback, streaming, and video player customization version: 1.0.0 tags: [video, video-player, streaming, hls, adaptive-bitrate] --- # Video Producer Skill I help you build video players, handle video streaming, and create engaging video experiences. ## What I Do **Video Playback:** - Custom video players with controls - Adaptive bitrate streaming (HLS, DASH) - Picture-in-picture mode - Fullscreen support **Video Features:** - Subtitles and captions - Quality selection - Playback speed control - Thumbnail previews **Streaming:** - Live video streaming - Video on demand (VOD) - Progressive download - Adaptive streaming ## Custom Video Player ```typescript // components/VideoPlayer.tsx 'use client' import { useRef, useState, useEffect } from 'react' interface VideoPlayerProps { src: string poster?: string title?: string } export function VideoPlayer({ src, poster, title }: VideoPlayerProps) { const videoRef = useRef(null) const [playing, setPlaying] = useState(false) const [currentTime, setCurrentTime] = useState(0) const [duration, setDuration] = useState(0) const [volume, setVolume] = useState(1) const [fullscreen, setFullscreen] = useState(false) const [showControls, setShowControls] = useState(true) useEffect(() => { const video = videoRef.current if (!video) return const updateTime = () => setCurrentTime(video.currentTime) const updateDuration = () => setDuration(video.duration) const handleEnded = () => setPlaying(false) video.addEventListener('timeupdate', updateTime) video.addEventListener('loadedmetadata', updateDuration) video.addEventListener('ended', handleEnded) return () => { video.removeEventListener('timeupdate', updateTime) video.removeEventListener('loadedmetadata', updateDuration) video.removeEventListener('ended', handleEnded) } }, []) const togglePlay = () => { if (!videoRef.current) return if (playing) { videoRef.current.pause() } else { videoRef.current.play() } setPlaying(!playing) } const handleSeek = (e: React.ChangeEvent) => { const time = parseFloat(e.target.value) setCurrentTime(time) if (videoRef.current) { videoRef.current.currentTime = time } } const handleVolumeChange = (e: React.ChangeEvent) => { const vol = parseFloat(e.target.value) setVolume(vol) if (videoRef.current) { videoRef.current.volume = vol } } const toggleFullscreen = () => { if (!videoRef.current) return if (!fullscreen) { videoRef.current.requestFullscreen() } else { document.exitFullscreen() } setFullscreen(!fullscreen) } const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60) const secs = Math.floor(seconds % 60) return `${mins}:${secs.toString().padStart(2, '0')}` } return (
setShowControls(true)} onMouseLeave={() => setShowControls(playing ? false : true)} > {title && (

{title}

)}