我试图更改React js中HTML5视频元素的currentTime,但它总是重置为零

问题描述 投票:0回答:1

我试图通过滑块更改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。

javascript html reactjs material-ui video-streaming
1个回答
0
投票

有类似的问题。对我来说,解决方案是在后端而不是前端。它与您将文件流式传输到前端的方式有关。就我而言,我首先使用了一种相当简单的方法,即通过管道传输整个文件。更正后的版本应该使用一种算法,仅传输您需要/请求的所需部分(字节)。

这篇文章将我推向了正确的方向: 如何修复“HTML5 currentTime 始终设置为零”

© www.soinside.com 2019 - 2024. All rights reserved.