我有一个很大的HTML5视频。我也在使用Chrome。 video元素具有@ViewChildren(ModalDirective) cellTemplates: QueryList<ModalDirective>;
cellTemplatesMap: any;
...
ngAfterContentInit() {
this.cellTemplatesMap = this.cellTemplates.reduce((acc, cur) => {
acc[cur.name] = cur.template;
return acc;
}, {});
}
属性,但是每次视频“循环播放”时,浏览器都会重新下载视频文件。我设置了loop
。但是,这不会阻止对相同文件的任何额外下载。我正在使用Amazon S3托管文件。 s3服务器还使用Cache-Control "max-age=15768000, private"
标头进行响应,这将导致使用Accepts Ranges
http响应代码来请求文件的数百次部分下载。
这是我的视频标签:
206
更新:
看来,最好的解决方案是阻止<video autoplay="" loop="" class="asset current">
<source src="https://mybucket.s3.us-east-2.amazonaws.com/myvideo.mp4">
</video>
标头与原始响应一起发送,而应使用200 http响应代码。如何做到这一点,以便通过Accept Ranges
文件完全缓存视频?
先谢谢了。
答案 0 :(得分:0)
Google chrome对文件捕获的大小有限制。在这种情况下,我先前的答案将无效。您应该使用类似file-compressor的名称,该资源可能能够充分压缩文件,从而使文件缓存符合条件。网络浏览器可以手动设置新的缓存大小,但是如果最终用户未指定其缓存与容纳长视频所需的空间一致,则此操作不可行。
答案 1 :(得分:0)
我不确定您面临的真正问题是什么。
Chrome可能会对其缓存的内容设置最大大小限制,如果是这种情况,那么不使用Range-Requests不会解决任何问题。
另一个可能的解释是,缓存媒体并不是一个简单的任务。
在没有看到文件的情况下,很难确定是哪种情况,但是您必须了解,要播放媒体,浏览器不需要提取整个文件。
例如,您可以很好地在
但是很可能会禁用Range-Requests,所以您必须知道,如果服务器不允许Range-Requests,某些浏览器(Safari)将无法播放媒体。
因此,即使那样,它也可能不是您想要的。
您可能要尝试的第一件事是针对网络使用情况优化视频。代替mp4,提供一个webm文件。对于相同的质量,这些通常会占用较少的空间,并且也许您会避免最大尺寸限制。
如果生成的文件仍然太大,那么肮脏的解决方案是使用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 );
<button id="streamVid">stream video</button>
<video id="out" controls muted autoplay loop></video>
答案 2 :(得分:0)
来到这里的人面临的一种可能性 - 开发工具在网络选项卡下有一个“禁用缓存”选项。启用后(意味着缓存被禁用)浏览器可能不会缓存视频,因此需要再次下载它们。 disable cache from network tab