training_data/apps/web/src/components/presentation/video-player/VideoControls.tsx

128 lines
2.8 KiB
TypeScript

import React, { useEffect, useRef, useContext, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import {
PlayIcon,
PauseIcon,
SpeakerWaveIcon,
SpeakerXMarkIcon,
Cog6ToothIcon,
ArrowsPointingOutIcon,
ArrowsPointingInIcon,
ChevronUpDownIcon,
SunIcon,
} from "@heroicons/react/24/solid";
import { VideoPlayerContext } from "./VideoPlayer";
import { formatTime } from "./utlis";
import { PlaybackSpeed } from "./type";
import Volume from "./ControlButtons/Volume";
import Brightness from "./ControlButtons/Brightness";
import Speed from "./ControlButtons/Speed";
import Play from "./ControlButtons/Play";
import Setting from "./ControlButtons/Setting";
import FullScreen from "./ControlButtons/FullScreen";
import TimeLine from "./ControlButtons/TimeLine";
export const Controls = () => {
const {
showControls,
setShowControls,
isSettingsOpen,
setIsSettingsOpen,
playbackSpeed,
setPlaybackSpeed,
videoRef,
isReady,
setIsReady,
isPlaying,
setIsSpeedOpen,
isSpeedOpen,
setIsPlaying,
bufferingState,
setBufferingState,
volume,
setVolume,
isMuted,
setIsMuted,
loadingProgress,
setLoadingProgress,
currentTime,
setCurrentTime,
duration,
setDuration,
brightness,
setBrightness,
isDragging,
setIsDragging,
isHovering,
isBrightnessOpen,
setIsBrightnessOpen,
setIsHovering,
progressRef,
} = useContext(VideoPlayerContext);
// 控制栏显示逻辑
useEffect(() => {
let timer: number;
if (!isHovering && !isDragging) {
timer = window.setTimeout(() => {
setShowControls(false);
}, 2000);
}
return () => {
if (timer) window.clearTimeout(timer);
};
}, [isHovering, isDragging]);
return (
<motion.div
layoutId="video-controls"
initial={false}
animate={{
opacity: showControls ? 1 : 0,
y: showControls ? 0 : 20,
}}
transition={{
duration: 0.2,
ease: "easeInOut",
}}
className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-4">
{/* 进度条 */}
<TimeLine></TimeLine>
{/* 控制按钮区域 */}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
{/* 播放/暂停按钮 */}
<Play></Play>
{/* 时间显示 */}
{duration && (
<span className="text-white text-xl">
{formatTime(currentTime)} / {formatTime(duration)}
</span>
)}
</div>
{/* 右侧控制按钮 */}
<div className="flex items-center space-x-4">
{/* 音量 */}
<Volume></Volume>
{/* 亮度 */}
<Brightness></Brightness>
{/* 倍速控制 */}
<Speed></Speed>
{/* 设置按钮 */}
<Setting></Setting>
{/* 全屏按钮 */}
<FullScreen></FullScreen>
</div>
</div>
</motion.div>
);
};
export default Controls;