video-producer
Expert in video playback, streaming, and video player customization
What this skill does
# 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<HTMLVideoElement>(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<HTMLInputElement>) => {
const time = parseFloat(e.target.value)
setCurrentTime(time)
if (videoRef.current) {
videoRef.current.currentTime = time
}
}
const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
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 (
<div
className="relative bg-black rounded-lg overflow-hidden"
onMouseEnter={() => setShowControls(true)}
onMouseLeave={() => setShowControls(playing ? false : true)}
>
{title && (
<div className="absolute top-0 left-0 right-0 p-4 bg-gradient-to-b from-black/70 to-transparent z-10">
<h3 className="text-white font-semibold">{title}</h3>
</div>
)}
<video
ref={videoRef}
src={src}
poster={poster}
onClick={togglePlay}
className="w-full"
/>
{showControls && (
<div className="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent">
{/* Progress Bar */}
<input
type="range"
min="0"
max={duration || 0}
value={currentTime}
onChange={handleSeek}
className="w-full mb-2"
/>
<div className="flex items-center gap-4">
{/* Play/Pause */}
<button
onClick={togglePlay}
className="text-white text-2xl hover:scale-110 transition"
>
{playing ? '⏸️' : '▶️'}
</button>
{/* Time */}
<span className="text-white text-sm">
{formatTime(currentTime)} / {formatTime(duration)}
</span>
{/* Volume */}
<div className="flex items-center gap-2">
<span className="text-white">🔊</span>
<input
type="range"
min="0"
max="1"
step="0.1"
value={volume}
onChange={handleVolumeChange}
className="w-20"
/>
</div>
<div className="flex-1" />
{/* Fullscreen */}
<button
onClick={toggleFullscreen}
className="text-white hover:scale-110 transition"
>
{fullscreen ? '⬛' : '⬜'}
</button>
</div>
</div>
)}
</div>
)
}
```
---
## HLS Streaming (Adaptive Bitrate)
```bash
npm install hls.js
```
```typescript
// components/HLSPlayer.tsx
'use client'
import { useEffect, useRef } from 'react'
import Hls from 'hls.js'
export function HLSPlayer({ src }: { src: string }) {
const videoRef = useRef<HTMLVideoElement>(null)
useEffect(() => {
const video = videoRef.current
if (!video) return
if (Hls.isSupported()) {
const hls = new Hls({
enableWorker: true,
lowLatencyMode: true
})
hls.loadSource(src)
hls.attachMedia(video)
hls.on(Hls.Events.MANIFEST_PARSED, () => {
console.log('HLS manifest loaded, quality levels:', hls.levels)
})
hls.on(Hls.Events.ERROR, (event, data) => {
console.error('HLS error:', data)
if (data.fatal) {
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
hls.startLoad()
break
case Hls.ErrorTypes.MEDIA_ERROR:
hls.recoverMediaError()
break
default:
hls.destroy()
break
}
}
})
return () => {
hls.destroy()
}
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// Native HLS support (Safari)
video.src = src
}
}, [src])
return <video ref={videoRef} controls className="w-full" />
}
```
---
## Picture-in-Picture
```typescript
// components/PIPVideoPlayer.tsx
'use client'
import { useRef, useState } from 'react'
export function PIPVideoPlayer({ src }: { src: string }) {
const videoRef = useRef<HTMLVideoElement>(null)
const [pipActive, setPipActive] = useState(false)
const togglePIP = async () => {
if (!videoRef.current) return
try {
if (!pipActive) {
await videoRef.current.requestPictureInPicture()
setPipActive(true)
} else {
await document.exitPictureInPicture()
setPipActive(false)
}
} catch (error) {
console.error('PIP error:', error)
}
}
return (
<div>
<video ref={videoRef} src={src} controls className="w-full" />
<button
onClick={togglePIP}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
>
{pipActive ? 'Exit PIP' : 'Enter PIP'}
</button>
</div>
)
}
```
---
## Subtitles/Captions
```typescript
// components/VideoWithSubtitles.tsx
'use client'
export function VideoWithSubtitles() {
return (
<video controls className="w-full">
<source src="/video.mp4" type="video/mp4" />
<track
kind="subtitles"
src="/subtitles/en.vtt"
srcLang="en"
label="English"
default
/>
<track
kind="subtitles"
src="/subtitles/es.vtt"
srcLang="es"
label="Español"
/>
<track
kind="subtitles"
src="/subtitles/fr.vtt"
srcLang="fr"
label="Français"
/>
</video>
)
}
```
**VTT Subtitle File:**
```vtt
WEBVTT
00:00:00.000 --> 00:00:02.000
Related in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.