HTML视频循环重新下载视频文件 [英] HTML video loop re-downloads video file

查看:152
本文介绍了HTML视频循环重新下载视频文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很大的HTML5视频.我也在使用Chrome. video元素具有loop属性,但是每次视频循环播放"时,浏览器都会重新下载视频文件.我已经设置了Cache-Control "max-age=15768000, private".但是,这不会阻止对相同文件的任何额外下载.我正在使用Amazon S3托管文件. s3服务器还以Accepts Ranges标头作为响应,这导致使用206 http响应代码来请求文件的几百次部分下载.

I have an HTML5 video that is rather large. I'm also using Chrome. The video element has the loop attribute but each time the video "loops", the browser re-downloads the video file. I have set Cache-Control "max-age=15768000, private". However, this does not prevent any extra downloads of the identical file. I am using Amazon S3 to host the file. Also the s3 server responds with the Accepts Ranges header which causes the several hundred partial downloads of the file to be requested with the 206 http response code.

这是我的视频标签:

<video autoplay="" loop="" class="asset current">
    <source src="https://mybucket.s3.us-east-2.amazonaws.com/myvideo.mp4">
</video>

更新:

看来,最好的解决方案是防止将Accept Ranges标头与原始响应一起发送,而应使用200 http响应代码.如何做到这一点,以便通过.htaccess文件完全缓存视频?

It seems that the best solution is to prevent the Accept Ranges header from being sent with the original response and instead use a 200 http response code. How can this be achieved so that the video is fully cached through an .htaccess file?

先谢谢了.

推荐答案

我不确定您面临的真正问题是什么.

I don't know for sure what's the real issue you are facing.

Chrome可能会对其缓存的内容设置最大大小限制,如果是这种情况,那么不使用Range-Requests不会解决任何问题.

It could be that Chrome has a max-size limit to what they'd cache, and if it the case, then not using Range-Requests wouldn't solve anything.

另一个可能的解释是,缓存媒体并不是真正的简单任务.
在没有看到文件的情况下,很难确定是哪种情况,但是必须了解,要播放媒体,浏览器不需要提取整个文件.
例如,您可以很好地在< audio>元素中播放视频文件,因为将不使用视频流,因此浏览器可以很好地完全忽略它,而仅下载音频流.不确定是否有,但是可以.大多数媒体格式实际上将文件中的音频和视频流分开,并且它们的字节位置在元数据中标记.
他们当然可以缓存他们执行的Range-Requests,但是我认为它们仍然很少见.

An other possible explanation is that caching media is not really a simple task.
Without seeing your file it's hard to tell for sure in which case you are, but you have to understand that to play a media, the browser doesn't need to fetch the whole file.
For instance, you can very well play a video file in an <audio> element, since the video stream won't be used, a browser could very well omit it completely and download only the audio stream. Not sure if any does, but they could. Most media formats do physically separate audio and video streams in the file and their byte positions are marked in the metadata.
They could certainly cache the Range-Requests they perform, but I think it's still quite rare they do.

但是很可能会禁用Range-Requests,所以您必须知道,如果服务器不允许Range-Requests,某些浏览器(Safari)将无法播放媒体.
因此,即使那样,它可能也不是您想要的.

But as tempting it might be to disable Range-Requests, you've to know that some browsers (Safari) will not play your media if your server doesn't allow Range-Requests.
So even then, it's probably not what you want.

您可能要尝试的第一件事是针对网络使用情况优化视频.代替mp4,提供一个webm文件.对于相同的质量,这些通常会占用较少的空间,也许您会避免最大尺寸限制.

The first thing you may want to try is to optimize your video for web usage. Instead of mp4, serve a webm file. These will generally take less space for the same quality and maybe you'll avoid the max-size limitation.

如果生成的文件仍然太大,那么肮脏的解决方案是使用MediaSource,以便将该文件保留在内存中,并且只需要提取一次即可.

If the resulting file is still too big, then a dirty solution would be to use a MediaSource so that the file is kept in memory and you need to fetch it only once.

在下面的示例中,该文件将仅以1MB的块的大小被完全提取一次,并在提取时由MediaSource流式传输,然后仅将内存中的数据用于循环播放:

In the following example, the file will be fetched entirely only once, by chunks of 1MB, streamed by the MediaSource as it's being fetched and then only the data in memory will be used for looping plays:

document.getElementById('streamVid').onclick = e => (async () => {

const url = 'https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm';
// you must know the mimeType of your video before hand.
const type = 'video/webm; codecs="vp8, vorbis"';
if( !MediaSource.isTypeSupported( type ) ) {
  throw 'Unsupported';
}

const source = new MediaSource();
source.addEventListener('sourceopen', sourceOpen);
document.getElementById('out').src = URL.createObjectURL( source );

// async generator Range-Fetcher
async function* fetchRanges( url, chunk_size = 1024 * 1024 ) {
  let chunk = new ArrayBuffer(1);
  let cursor = 0;
  while( chunk.byteLength ) {
    const resp = await fetch( url, {
      method: "get",
        headers: { "Range": "bytes=" + cursor + "-" + ( cursor += chunk_size ) }
      }
    )
    chunk = resp.ok && await resp.arrayBuffer();
    cursor++; // add one byte for next iteration, Ranges are inclusive
    yield chunk;
  }
}
// set up our MediaSource
async function sourceOpen() {
  const buffer = source.addSourceBuffer( type );
  buffer.mode = "sequence";
  // waiting forward to appendAsync...
  const appendBuffer = ( chunk ) => {
    return new Promise( resolve => {
      buffer.addEventListener( 'update', resolve, { once: true } );
      buffer.appendBuffer( chunk );
    } );
  }
  // while our RangeFetcher is running
  for await ( const chunk of fetchRanges(url) ) {
    if( chunk ) { // append to our MediaSource
      await appendBuffer( chunk );
    }
    else { // when done
      source.endOfStream();
    }
  }
}
})().catch( console.error );

<button id="streamVid">stream video</button>
<video id="out" controls muted autoplay loop></video>

这篇关于HTML视频循环重新下载视频文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆