feat: Enhance video playback stability, integrate more menu into control visibility, and improve player UI responsiveness.

This commit is contained in:
kuekhaoyang
2025-12-26 21:12:09 +08:00
parent cb04d276bb
commit ff18e10af5
8 changed files with 70 additions and 27 deletions
@@ -4,8 +4,10 @@ interface UseControlsVisibilityProps {
isPlaying: boolean;
showControls: boolean;
showSpeedMenu: boolean;
showMoreMenu: boolean;
setShowControls: (show: boolean) => void;
setShowSpeedMenu: (show: boolean) => void;
setShowMoreMenu: (show: boolean) => void;
controlsTimeoutRef: React.MutableRefObject<NodeJS.Timeout | null>;
speedMenuTimeoutRef: React.MutableRefObject<NodeJS.Timeout | null>;
mouseMoveThrottleRef: React.MutableRefObject<NodeJS.Timeout | null>;
@@ -15,25 +17,46 @@ export function useControlsVisibility({
isPlaying,
showControls,
showSpeedMenu,
showMoreMenu,
setShowControls,
setShowSpeedMenu,
setShowMoreMenu,
controlsTimeoutRef,
speedMenuTimeoutRef,
mouseMoveThrottleRef
}: UseControlsVisibilityProps) {
useEffect(() => {
if (!isPlaying) return;
// Shared hide controls logic
const hideControls = useCallback(() => {
if (controlsTimeoutRef.current) {
clearTimeout(controlsTimeoutRef.current);
}
controlsTimeoutRef.current = setTimeout(() => {
if (isPlaying && !showSpeedMenu && !showMoreMenu) {
setShowControls(false);
}
}, 3000);
}, [isPlaying, showSpeedMenu, showMoreMenu, setShowControls, controlsTimeoutRef]);
const hideControls = () => {
// Force controls to show when paused
useEffect(() => {
if (!isPlaying) {
setShowControls(true);
if (controlsTimeoutRef.current) {
clearTimeout(controlsTimeoutRef.current);
}
controlsTimeoutRef.current = setTimeout(() => {
if (isPlaying && !showSpeedMenu) {
setShowControls(false);
}
}, 3000);
};
} else {
// When resuming play, start the timer to hide controls
hideControls();
}
}, [isPlaying, setShowControls, hideControls, controlsTimeoutRef]);
useEffect(() => {
if (!isPlaying || showSpeedMenu || showMoreMenu) {
if (controlsTimeoutRef.current) {
clearTimeout(controlsTimeoutRef.current);
}
return;
}
hideControls();
@@ -40,7 +40,15 @@ export function usePlaybackControls({
if (isPlaying) {
videoRef.current.pause();
} else {
videoRef.current.play();
const playPromise = videoRef.current.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
// Ignore AbortError: The play() request was interrupted by a call to pause().
if (error.name !== 'AbortError') {
console.error('Playback failed:', error);
}
});
}
}
}, [isPlaying, videoRef]);
@@ -58,7 +58,8 @@ export function useDesktopPlayerLogic({
setIsSkipForwardAnimatingOut, setIsSkipBackwardAnimatingOut,
setShowVolumeBar, setToastMessage, setShowToast,
isCastAvailable, setIsCastAvailable,
isCasting, setIsCasting
isCasting, setIsCasting,
showMoreMenu, setShowMoreMenu
} = state;
const playbackControls = usePlaybackControls({
@@ -94,8 +95,8 @@ export function useDesktopPlayerLogic({
});
const controlsVisibility = useControlsVisibility({
isPlaying, showControls, showSpeedMenu,
setShowControls, setShowSpeedMenu,
isPlaying, showControls, showSpeedMenu, showMoreMenu,
setShowControls, setShowSpeedMenu, setShowMoreMenu,
controlsTimeoutRef, speedMenuTimeoutRef, mouseMoveThrottleRef
});