VideoPlayer.tsx
1'use client'
2
3import { useRef, useState } from 'react'
4import { Play, Pause, Volume2, Volume1, VolumeX, Volume } from 'lucide-react'
5
6interface VideoPlayerProps {
7 src: string
8}
9
10export function VideoPlayer({ src }: VideoPlayerProps) {
11 const videoRef = useRef<HTMLVideoElement>(null)
12 const [isPlaying, setIsPlaying] = useState(false)
13 const [progress, setProgress] = useState(0)
14 const [volume, setVolume] = useState(1)
15
16 const togglePlay = () => {
17 if (videoRef.current) {
18 if (isPlaying) {
19 videoRef.current.pause()
20 } else {
21 videoRef.current.play()
22 }
23 setIsPlaying(!isPlaying)
24 }
25 }
26
27 const handleTimeUpdate = () => {
28 if (videoRef.current) {
29 const progress =
30 (videoRef.current.currentTime / videoRef.current.duration) * 100
31 setProgress(progress)
32 }
33 }
34
35 const handleProgressClick = (e: React.MouseEvent<HTMLDivElement>) => {
36 if (videoRef.current) {
37 const rect = e.currentTarget.getBoundingClientRect()
38 const x = e.clientX - rect.left
39 const percentage = x / rect.width
40 videoRef.current.currentTime = percentage * videoRef.current.duration
41 }
42 }
43
44 const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
45 const newVolume = parseFloat(e.target.value)
46 setVolume(newVolume)
47 if (videoRef.current) {
48 videoRef.current.volume = newVolume
49 }
50 }
51
52 const getVolumeIcon = () => {
53 if (volume === 0) return <VolumeX className="h-4 w-4" />
54 if (volume < 0.3) return <Volume className="h-4 w-4" />
55 if (volume < 0.7) return <Volume1 className="h-4 w-4" />
56 return <Volume2 className="h-4 w-4" />
57 }
58
59 return (
60 <div className="markdown-video-player group relative overflow-hidden rounded-lg bg-gray-900">
61 <video
62 ref={videoRef}
63 src={src}
64 className="w-full"
65 onTimeUpdate={handleTimeUpdate}
66 onClick={togglePlay}
67 />
68
69 <div className="absolute bottom-0 left-0 right-0 bg-black/50 p-2 opacity-0 backdrop-blur-sm transition-opacity group-hover:opacity-100">
70 <div className="flex items-center gap-2">
71 <button
72 onClick={togglePlay}
73 className="text-white transition-colors hover:text-purple-400"
74 >
75 {isPlaying ?
76 <Pause className="h-6 w-6" />
77 : <Play className="h-6 w-6" />}
78 </button>
79
80 <div
81 className="h-1 flex-1 cursor-pointer rounded-full bg-gray-700"
82 onClick={handleProgressClick}
83 >
84 <div
85 className="h-full rounded-full bg-purple-500"
86 style={{ width: `${progress}%` }}
87 />
88 </div>
89
90 <div className="flex w-24 items-center gap-1">
91 <span className="text-white">{getVolumeIcon()}</span>
92 <input
93 type="range"
94 min="0"
95 max="1"
96 step="0.1"
97 value={volume}
98 onChange={handleVolumeChange}
99 className="w-full"
100 />
101 </div>
102 </div>
103 </div>
104 </div>
105 )
106}
107