Can*_*yer 7 html javascript google-chrome http amazon-s3
我有一个很大的HTML5视频。我也在使用Chrome。video元素具有loop属性,但是每次视频“循环播放”时,浏览器都会重新下载视频文件。我已经设定了Cache-Control "max-age=15768000, private"。但是,这不会阻止对相同文件的任何额外下载。我正在使用Amazon S3托管文件。s3服务器还使用Accepts Ranges标头进行响应,该标头导致使用206http响应代码请求文件的数百次部分下载。
这是我的视频标签:
<video autoplay="" loop="" class="asset current">
<source src="https://mybucket.s3.us-east-2.amazonaws.com/myvideo.mp4">
</video>
Run Code Online (Sandbox Code Playgroud)
更新:
似乎最好的解决方案是阻止Accept Ranges标头与原始响应一起发送,而使用200 http响应代码。如何做到这一点,以便通过.htaccess文件完全缓存视频?
提前致谢。
我不确定您面临的真正问题是什么。
Chrome 可能对缓存的内容有最大大小限制,如果是这种情况,那么不使用 Range-Requests 不会解决任何问题。
另一种可能的解释是缓存媒体并不是一个简单的任务。
如果没有看到您的文件,就很难确定您属于哪种情况,但您必须了解,要播放媒体,浏览器不需要获取整个文件。
例如,您可以很好地在 <audio> 元素中播放视频文件,因为不会使用视频流,浏览器很可能完全忽略它并仅下载音频流。不确定是否有,但他们可以。大多数媒体格式确实在文件中物理分离音频和视频流,并且它们的字节位置在元数据中标记。
他们当然可以缓存他们执行的范围请求,但我认为他们这样做的情况仍然相当罕见。
但禁用范围请求可能很诱人,您必须知道,如果您的服务器不允许范围请求,某些浏览器(Safari)将不会播放您的媒体。
所以即使如此,这可能也不是您想要的。
您可能想要尝试的第一件事是优化您的视频以供网络使用。提供 webm 文件而不是 mp4。对于相同的质量,这些通常会占用更少的空间,也许您可以避免最大大小的限制。
如果生成的文件仍然太大,那么一个肮脏的解决方案是使用 MediaSource,以便将文件保存在内存中,并且您只需要获取它一次。
在以下示例中,文件将仅按 1MB 的块完全获取一次,并在获取时由 MediaSource 进行流式传输,然后仅将内存中的数据用于循环播放:
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 );Run Code Online (Sandbox Code Playgroud)
<button id="streamVid">stream video</button>
<video id="out" controls muted autoplay loop></video>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
188 次 |
| 最近记录: |