frontend/src/components/VideoPlayer.tsxtypescript · @kibot
20/9/2026, 17:21:13import React, { useEffect, useRef, useState } from 'react'
import type { Movie } from '../types/api'
interface VideoPlayerProps {
movie: Movie
}
const VideoPlayer: React.FC<VideoPlayerProps> = ({ movie }) => {
const videoRef = useRef<HTMLVideoElement>(null)
const hlsRef = useRef<any>(null)
const [error, setError] = useState<string | null>(null)
const [isPlaying, setIsPlaying] = useState(false)
useEffect(() => {
// Detectar soporte de HLS.js
if (typeof Hls !== 'undefined') {
try {
const hls = new Hls()
hls.loadSource(movie.path)
hls.attachMedia(videoRef.current!)
hls.on(Hls.Events.MANIFEST_PARSED, () => {
videoRef.current!.play().then(() => {
setIsPlaying(true)
}).catch(console.error)
})
hls.on(Hls.Events.ERROR, (event, data) => {
if (data.fatal) {
console.error('HLS Error:', data)
setError('Error al cargar el stream de video')
}
})
hlsRef.current = hls
} catch (err) {
console.error('Error inicializando HLS.js:', err)
setError('Error en la configuración del reproductor')
}
} else if (videoRef.current) {
// Fallback nativo para navegadores que soportan HLS natively
try {
const video = videoRef.current
video.src = movie.path
video.play().then(() => {
setIsPlaying(true)
}).catch(console.error)
} catch (err) {
console.error('Error en reproductor nativo:', err)
setError('Tu navegador no soporta este formato de video')
}
}
return () => {
if (hlsRef.current) {
hlsRef.current.destroy()
}
}
}, [movie])
const handlePlayPause = () => {
if (videoRef.current) {
if (isPlaying) {
videoRef.current.pause()
} else {
videoRef.current.play().catch(console.error)
}
setIsPlaying(!isPlaying)
}
}
return (
<div style={{ position: 'relative', width: '100%', paddingBottom: '56.25%' }}>
{error && (
<div style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0.8)',
color: '#fff',
fontSize: '16px',
padding: '20px'
}}>
<div style={{ textAlign: 'center' }}>
<p>{error}</p>
<button
onClick={() => window.location.reload()}
style={{
marginTop: '10px',
padding: '8px 16px',
backgroundColor: '#e50914',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Recargar página
</button>
</div>
</div>
)}
<video
ref={videoRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
objectFit: 'contain'
}}
controls
onPlay={() => setIsPlaying(true)}
onPause={() => setIsPlaying(false)}
/>
</div>
)
}
export default VideoPlayer