以下是我使用React.js编写的字体代码

import React, { useEffect, useRef } from 'react';

const VideoPage = () => {
  const videoInited = useRef(false)

  useEffect(() => {
    const video = document.querySelector("#stream-media-video") as HTMLMediaElement;

    // Using Bento4 to parse my mp4 video file
    // mp4info test.mp4 | grep Codec
    const mimeCodec = 'video/mp4; codecs="avc1.64081F, mp4a.40.2"';

    if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
      const mediaSource = new MediaSource();
      video.src = URL.createObjectURL(mediaSource);
      mediaSource.addEventListener("sourceopen", sourceOpen);
    } else {
      console.error("Unsupported MIME type or codec: ", mimeCodec);
    }

    function sourceOpen(_) {
      console.log('[mediaSource sourceopen event trigger]: ', this.readyState); // open
      const mediaSource = this;

      const playBtn = document.querySelector('.play-btn');
      const init = () => {
        const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);

        // Get some video clips through xhr request (the video file is 1.5M in total, first get the first 1M part, and then get the next 0.5M part)
        fetchAB("/api/media/testmp4/part-v2?start=0&end=1000000", function (buf) {
          sourceBuffer.addEventListener('error', (e) => {
            console.error("sourceBuffer error", e);
          });
          
          sourceBuffer.addEventListener("updateend", function (_) {
            // mediaSource.endOfStream();

            video.play();
            videoInited.current = true;
            playBtn.removeEventListener("click", init);
  
          });
          sourceBuffer.appendBuffer(buf);

          // get the next 0.5M part
          fetchAB("/api/media/testmp4/part-v2?start=1000000&end=2000000", function (secondBuf){
            sourceBuffer.appendBuffer(secondBuf);
          });

        });
      }
      playBtn.addEventListener("click", init)

    }

    function fetchAB(url, cb) {
      const xhr = new XMLHttpRequest();
      xhr.open("get", url);
      xhr.responseType = "arraybuffer";
      xhr.onload = function () {
        cb(xhr.response);
      };
      xhr.send();
    }

  }, [])

  const handleClickPlay = () => {
    const video = document.querySelector("video")
    if (videoInited.current) {
      video.play()
    }
  }

  return (
    <div>
      <video 
        id='stream-media-video'
        width="400px"
        height="400px"
        style={{
          objectFit: 'contain',
        }}
        controls
      />
      <div>
        <button className='play-btn' onClick={handleClickPlay}>click to play video</button>
      </div>
    </div>
  )
}

export default VideoPage

下面是我的后端代码,

  app.get("/api/media/testmp4/part-v2", function (req, res) {
    const {
      start,
      end,
    } = req.query;
    const mp4FilePath = "test.mp4";
    const _start = Number(start);
    const videoSize = fs.statSync(mp4FilePath).size;
    const _end = Math.min(Number(end), videoSize - 1);

    // Get video clips and return them to the front end
    const videoStream = fs.createReadStream(mp4FilePath, { 
      start: _start, 
      end: _end,
    });

    videoStream.pipe(res);
  });

视频播放器中的进度条显示剩余视频剪辑尚未加载,无法继续播放.这是我的问题截图.

enter image description here

主控台没有错误,如何让视频继续播放?

推荐答案

"I have controlled the returned file byte range on the server side:
Math.min(Number(end), videoSize - 1)"

看着:

const _end = Math.min(Number(end), videoSize - 1);

Math.min将从这两个输入数字返回smallest one.
您的end小于videoSize-1,因此现在它被用作返回到您的应用中进行播放的字节限制:

 var End  : 1000000
(Size-1)  : 1499999
file Size : 1500000

"The progress bar in the video player shows that the remaining video clip data has not been loaded and it cannot continue to play."

修复:

  • 使用已知的文件大小(获取所有数据,不剩余数据):

    fetchAB("/api/media/testmp4/part—v2?start = 0 end = 1500000 ");&

  • 如果文件大小未知,则使用一个非常大的数字(真持续时间是新的最小值):

    FetchAB("/api/media/testmp4/part-v2?start=0&;end=999999999999");

Reactjs相关问答推荐

滚动事件监听器在Next.js客户端组件中不触发

useTranslation不会在languageChanged上重新呈现组件

UseEffect和useSelector的奇怪问题导致无限循环

如何通过回调函数获取多个值?

useCallback()是否应该用于作为prop传递给子组件的函数,即使该组件包装在memo()中?

如何使用.Aggregate从多个集合中获取数据,包括使用Mongoose+NextJS的SUM值

useEffect不重新渲染

如何在我的 React 应用程序中仅显示我的 Register 组件

当我无法引用模态组件时,如何使模态组件在 Next.js/React 中管理自己的状态?

错误:无法获取 RSC 负载.返回浏览器导航

我发送的 prop 的值不会改变.如果成功登录,导航栏中的 prop 必须为 true.我从后端得到 200 ok

无法读取未定义的属性(阅读 'editQuoteModalShown')reactredux

Redux Toolkit 配置,是否适用于全栈应用程序?

基于标记名的博客详细信息分组没有发生

react - 警告:列表中的每个子元素都应该有一个独特的 keys props ,即使我已经设置了 keys

使用 useRef(uuid()) 的目的是什么?

找不到元素 - 这是参考问题吗?

axios post方法中的请求失败,状态码为500错误

React - useParams() 不会失败 null / undefined 判断

仅react material 表前端分页