128 lines
2.8 KiB
TypeScript
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;
|