视频停止缓冲

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

我有一个 4 个视频和预加载器,当所有视频都完全缓冲时它应该隐藏

<div id="preload">
    <h1>
        Download...
    </h1>
</div>
<video preload="auto" class="active">
<source src="video1.mp4" type='video/mp4;'>
</video>
<video  preload="auto">
<source src="video2.mp4" type='video/mp4;'>
</video>
<video preload="auto">
<source src="video3.mp4" type='video/mp4;'>
</video>
<video preload="auto">
<source src="video4.mp4" type='video/mp4;'>
</video>

有检查视频是否缓冲的代码

preload = [];
preloadOverlay = document.querySelector('#preload');
videos =  document.querySelectorAll("video")
    [...videos].forEach(function(video, index) {
        video.addEventListener('canplay', function(){
            let timerId = setTimeout(function tick() {
                // console.log(preload)
                // console.log(video.buffered.end(0), video.duration)
                if(preload.length < 4)
                {
                    if(video.buffered.end(0) === video.duration)
                    {
                        preload.push(index)
                    }
                    timerId = setTimeout(tick, 200);
                }
                else if(preload.length === 4)
                {
                    clearTimeout(timerId);
                    preloadOverlay.classList.add('hide');
                }
                
            }, 200);
        })  
    })

但有时缓冲会停止,例如所有视频都是3秒长,但缓冲会在2秒停止

我将我的代码稍微更改为

[...videos].forEach(function(video, index) {
    video.addEventListener("canplaythrough", function() {
        preload.push(index)
      });
      let timerId = setTimeout(function tick() {
        if(preload.length < 4)
        {
            console.log(preload)
            console.log(video.buffered.end(0), video.duration)
            timerId = setTimeout(tick, 200);
        }
        else if(preload.length === 4)
        {
            clearTimeout(timerId)
            preloadOverlay.classList.add('hide')
            layoutAnimation(timeoutClassRemover)
        }        
    }, 200);
})

但是,一两个视频仍然没有加载到最后,并且随机停止

javascript html html5-video buffering
1个回答
0
投票

我不会为这个任务使用计时器。从我的角度来看,Promises 看起来更适合这里。

此外,我建议删除类型末尾的

;
video/mp4

如果有帮助,请告诉我。

// just to make the snippet working
const testVideoUrl = 'https://r2---sn-ntqe6n7r.c.2mdn.net/videoplayback/id/97eca827be163084/itag/15/source/doubleclick/requiressl/yes/ratebypass/yes/mime/video%2Fmp4/ip/0.0.0.0/ipbits/0/expire/2144448000/sparams/expire,id,ip,ipbits,itag,mh,mime,mip,mm,mn,ms,mv,mvi,pl,ratebypass,requiressl,source/signature/160FEBC1E31299C398B4F585BB3AC111D899FB8D.4E8EB91A32577DC9954E0EB1CED4109081DE6B71/key/cms1/cms_redirect/yes/mh/Hp/mip/60.241.173.252/mm/42/mn/sn-ntqe6n7r/ms/onc/mt/1679898045/mv/m/mvi/2/pl/23/file/file.mp4'

const preloadPromises = [];
const preloadOverlay = document.querySelector('#preload');
const videos =  document.querySelectorAll("video");
[...videos].forEach((video, index) => {
  // just for the test the URL is assigned from the script
  video.src = testVideoUrl;
  let resolve;
  const promise = new Promise((_resolve) => {
    resolve = _resolve;
  });
  video.addEventListener('canplaythrough', resolve);
  preloadPromises.push(promise);
});

// wait for all videos to precache
Promise.all(preloadPromises).then(() => {
  console.log('all the videos can be played through');
  // all the videos can be played through
  preloadOverlay.classList.add('hide');
});
<html>
  <body>
    <div id="preload">
      <h1>
        Download...
      </h1>
    </div>
    <video preload="auto" class="active">
      <source src="video1.mp4" type='video/mp4'>
    </video>
    <video  preload="auto">
      <source src="video2.mp4" type='video/mp4'>
    </video>
    <video preload="auto">
      <source src="video3.mp4" type='video/mp4'>
    </video>
    <video preload="auto">
      <source src="video4.mp4" type='video/mp4'>
    </video>
  </body>
</html>

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