Reproductor de video con Claude Code
Aprenda a implementar un reproductor de video usando Claude Code. Incluye ejemplos practicos de codigo.
カスタム動画プレーヤーをClaude Codeで作る
デフォルトのブラウザ動画プレーヤーではデザインの統一が難しく、機能も限定されます。Claude Codeを使えば、ブランドに合ったデザインで、再生速度変更・字幕・ピクチャーインピクチャーなどの機能を備えたカスタムプレーヤーを構築できます。
プレーヤーの要件
> HTML5 Videoベースのカスタム動画プレーヤーを作って。
> 再生/一時停止、シークバー、音量、再生速度変更、
> フルスクリーン、ピクチャーインピクチャー、字幕表示に対応して。
メインプレーヤーコンポーネント
// src/components/VideoPlayer.tsx
'use client';
import { useRef, useState, useEffect } from 'react';
interface VideoPlayerProps {
src: string;
poster?: string;
subtitles?: { src: string; label: string; lang: string }[];
}
export function VideoPlayer({ src, poster, subtitles }: VideoPlayerProps) {
const videoRef = useRef<HTMLVideoElement>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [volume, setVolume] = useState(1);
const [playbackRate, setPlaybackRate] = useState(1);
const [showControls, setShowControls] = useState(true);
const video = videoRef.current;
useEffect(() => {
if (!video) return;
const handleTimeUpdate = () => setCurrentTime(video.currentTime);
const handleLoadedMetadata = () => setDuration(video.duration);
video.addEventListener('timeupdate', handleTimeUpdate);
video.addEventListener('loadedmetadata', handleLoadedMetadata);
return () => {
video.removeEventListener('timeupdate', handleTimeUpdate);
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
};
}, [video]);
const togglePlay = () => {
if (!video) return;
if (video.paused) {
video.play();
setIsPlaying(true);
} else {
video.pause();
setIsPlaying(false);
}
};
const handleSeek = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!video) return;
const time = Number(e.target.value);
video.currentTime = time;
setCurrentTime(time);
};
const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!video) return;
const vol = Number(e.target.value);
video.volume = vol;
setVolume(vol);
};
const changePlaybackRate = (rate: number) => {
if (!video) return;
video.playbackRate = rate;
setPlaybackRate(rate);
};
const toggleFullscreen = () => {
const container = videoRef.current?.parentElement;
if (!container) return;
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
container.requestFullscreen();
}
};
const togglePiP = async () => {
if (!video) return;
if (document.pictureInPictureElement) {
await document.exitPictureInPicture();
} else {
await video.requestPictureInPicture();
}
};
const formatTime = (seconds: number) => {
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60);
return `${m}:${s.toString().padStart(2, '0')}`;
};
return (
<div
className="relative group bg-black rounded-xl overflow-hidden"
onMouseEnter={() => setShowControls(true)}
onMouseLeave={() => isPlaying && setShowControls(false)}
>
<video
ref={videoRef}
src={src}
poster={poster}
onClick={togglePlay}
className="w-full cursor-pointer"
>
{subtitles?.map((sub) => (
<track key={sub.lang} kind="subtitles" src={sub.src} label={sub.label} srcLang={sub.lang} />
))}
</video>
{/* コントロールバー */}
<div className={`absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-4 transition-opacity ${showControls ? 'opacity-100' : 'opacity-0'}`}>
{/* シークバー */}
<input
type="range"
min={0}
max={duration}
value={currentTime}
onChange={handleSeek}
className="w-full h-1 mb-3 accent-blue-500"
/>
<div className="flex items-center justify-between text-white text-sm">
<div className="flex items-center gap-3">
<button onClick={togglePlay} className="text-xl">
{isPlaying ? '⏸' : '▶'}
</button>
<span>{formatTime(currentTime)} / {formatTime(duration)}</span>
<input
type="range"
min={0}
max={1}
step={0.1}
value={volume}
onChange={handleVolumeChange}
className="w-20 h-1 accent-white"
/>
</div>
<div className="flex items-center gap-3">
<select
value={playbackRate}
onChange={(e) => changePlaybackRate(Number(e.target.value))}
className="bg-transparent text-white text-sm"
>
{[0.5, 0.75, 1, 1.25, 1.5, 2].map((rate) => (
<option key={rate} value={rate} className="text-black">
{rate}x
</option>
))}
</select>
<button onClick={togglePiP} title="ピクチャーインピクチャー">🖼</button>
<button onClick={toggleFullscreen} title="フルスクリーン">⛶</button>
</div>
</div>
</div>
</div>
);
}
キーボードショートカット
// src/hooks/useVideoShortcuts.ts
import { useEffect } from 'react';
export function useVideoShortcuts(videoRef: React.RefObject<HTMLVideoElement>) {
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
const video = videoRef.current;
if (!video) return;
switch (e.key) {
case ' ':
e.preventDefault();
video.paused ? video.play() : video.pause();
break;
case 'ArrowRight':
video.currentTime = Math.min(video.currentTime + 10, video.duration);
break;
case 'ArrowLeft':
video.currentTime = Math.max(video.currentTime - 10, 0);
break;
case 'f':
document.fullscreenElement
? document.exitFullscreen()
: video.parentElement?.requestFullscreen();
break;
case 'm':
video.muted = !video.muted;
break;
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [videoRef]);
}
使い方の例
<VideoPlayer
src="/videos/demo.mp4"
poster="/images/poster.jpg"
subtitles={[
{ src: '/subtitles/ja.vtt', label: '日本語', lang: 'ja' },
{ src: '/subtitles/en.vtt', label: 'English', lang: 'en' },
]}
/>
関連記事
メディア関連ではオーディオプレーヤーの実装、アクセシビリティ対応はアクセシビリティ実装ガイドもご覧ください。
Web動画のフォーマットやエンコーディングについてはMDN Web Docs(developer.mozilla.org)が詳しいです。
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
7 comprobaciones antes de publicar cada día un artículo multilingüe sobre Claude Code
Una lista práctica para publicar artículos multilingües sobre Claude Code todos los días sin olvidar idiomas, romper CTAs ni dejar páginas antiguas en producción.
Que es Codex Automations y como dejar que la IA gestione contenido mientras duermes
Guia practica para usar Codex Automations en analitica, articulos, CTA, despliegue y monetizacion.
Claude Code × GCP Cloud Functions Guía Completa | Desarrollo Serverless Ultrarrápido
Optimiza GCP Cloud Functions con Claude Code. Implementa triggers HTTP/Pub/Sub/Firestore, pruebas locales y automatización de despliegues con ejemplos de código reales de la experiencia de Masa.