我试图通过滑块更改React JS中HTML5视频元素的
currentTime
,但它重置为0。每当我更改滑块时,滑块handleChange
都会设置videoRef.current.currentTime = newValue
的值,即
const handleChange = (e, newValue) => {
videoRef.current.currentTime = `${newValue}`;
setVideoTime(newValue);
};
然后
handleTimeUpdate
调用,但它的事件值为 0,即
const handleTimeUpdate = (e) => {
setVideoTime(e.target.currentTime); // it always sets to zero whenever there is change in slider value.
if (e.target.currentTime >= duration) {
handlePause();
setIsPlaying(false);
setVideoTime(0);
}
};
这是完整的组件
import React, { useState, useRef, useEffect, memo } from 'react';
import { Stack, IconButton, Typography } from '@mui/material';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import PauseIcon from '@mui/icons-material/Pause';
import ContentCutIcon from '@mui/icons-material/ContentCut';
import Slider from '@mui/material/Slider';
import { useSelector } from 'react-redux';
import { VideoPlayerGrayColor } from 'theme/colors';
import { calculateTimeWithSeconds } from 'utils/helperFunction';
import { STAGING_URL } from 'utils/constants';
function VideoViewer({ handleTrim }) {
const activeMedia = useSelector(state => state?.mediaLibrary?.activeMedia)
const videoRef = useRef(null);
const [videoTime, setVideoTime] = useState(0); // Corrected initialization
const [isPlaying, setIsPlaying] = useState(false);
const [duration, setDuration] = useState(0);
const [src, setSrc] = useState(`${STAGING_URL}${activeMedia?.uploaded_file}`)
const handleChange = (e, newValue) => {
videoRef.current.currentTime = `${newValue}`;
setVideoTime(newValue);
};
const handleTimeUpdate = (e) => {
setVideoTime(e.target.currentTime);
if (e.target.currentTime >= duration) {
handlePause();
setIsPlaying(false);
setVideoTime(0);
}
};
const handlePause = () => {
setIsPlaying(false);
videoRef.current.pause();
};
const togglePlayPause = () => {
if (videoRef.current.paused) {
if (videoRef.current.currentTime >= duration) {
videoRef.current.currentTime = '0';
}
videoRef.current.play();
} else {
videoRef.current.pause();
}
setIsPlaying(p => !p);
};
const handleVideoLoaded = () => {
const duration = videoRef.current?.duration || 0;
setDuration(duration);
};
useEffect(() => {
setSrc(`${STAGING_URL}${activeMedia?.uploaded_file}`);
}, [activeMedia])
return (
<Stack width="100%" height="100%" gap={1}>
<IconButton onClick={handleTrim} sx={{ borderRadius: '50%', width: 30, padding: '8px 20px', border: "1px solid #E1E1E6" }}>
<ContentCutIcon />
</IconButton>
<video
onProgress={handleTimeUpdate}
id="viewer"
style={{ aspectRatio: "16/9", borderRadius: '4px' }}
width="100%"
height="100%"
ref={videoRef}
src={src}
onLoadedMetadata={handleVideoLoaded}
onTimeUpdate={handleTimeUpdate}
/>
<Stack direction="row" justifyContent="flex-end" alignItems="center">
<Stack direction="row" minWidth="55%" justifyContent="space-between" alignItems="center">
<IconButton onClick={togglePlayPause} disableRipple>
{isPlaying ? <PauseIcon sx={{ color: VideoPlayerGrayColor, fontSize: "2rem" }} /> : <PlayArrowIcon sx={{ color: VideoPlayerGrayColor, fontSize: "2rem" }} />}
</IconButton>
<Stack minWidth="25%">
<Slider
value={videoTime}
onChange={handleChange}
scale={calculateTimeWithSeconds}
valueLabelDisplay="auto"
max={duration}
/>
<Typography textAlign="end" color={() => VideoPlayerGrayColor} fontSize={12} fontWeight={500}>{calculateTimeWithSeconds(videoTime)} / {calculateTimeWithSeconds(duration)}</Typography>
</Stack>
</Stack>
</Stack>
</Stack>
);
}
export default memo(VideoViewer);
我想通过mui的滑块改变视频的
currentTime
,但是每当滑块值有任何变化时它总是设置为0。
有类似的问题。对我来说,解决方案是在后端而不是前端。它与您将文件流式传输到前端的方式有关。就我而言,我首先使用了一种相当简单的方法,即通过管道传输整个文件。更正后的版本应该使用一种算法,仅传输您需要/请求的所需部分(字节)。
这篇文章将我推向了正确的方向: 如何修复“HTML5 currentTime 始终设置为零”