admin 管理员组文章数量: 1086019
I have a service worker that catches my page's requests (fetch
event), and when the URL matches a certain pattern, it would fetch another URL and replace the response with that new content.
It works perfectly for text data (JS, XML...) or binary data (e.g. images), but when it es to video, there is a glitch.
I am using Chrome 41 on OSX.
This is the simplified code of my worker:
self.addEventListener('fetch', function(event) {
var url = event.request.url;
console.log('SW: fetch', url);
if (/\.mp4$/.test(url)) {
url = '.mp4';
var options = {
credentials: 'include',
mode: 'no-cors'
};
event.respondWith(fetch(url, options));
}
});
And this is the simplified code in my HTML page:
navigator.serviceWorker.register('sw.js').then(function(reg) {
console.info('ServiceWorker registration successful for', reg.scope);
var video = document.createElement('video');
video.src = '/video.mp4';
video.controls = true;
video.autoplay = true;
video.onerror = function(err) {
console.error('Video load fail', err);
}
video.onload = function(data) {
console.info('Video load success');
}
document.body.appendChild(video);
}).catch(function(err) {
console.error('ServiceWorker registration failed:', err);
});
The first time you load the page, the worker installs, so the video request is not caught, thus failing. But when you reload the page (without cleaning the cache), it is successfully caught, and the worker successfully loads the video (HTTP 200 in its inspector), but for some reason, the main page throws a net::ERR_FAILED
.
And I cannot manually read/stream it, because it es from a different origin, resulting in an "opaque" Response type:
UPDATE: updating to Chrome 42, the error is now HTTP 400 Service Worker Fallback Required (from ServiceWorker)
. Strange thing is that the source code (line 510) indicates that it should only be raised when CORS headers are missing, but here the mode is no-cors
.
I have a service worker that catches my page's requests (fetch
event), and when the URL matches a certain pattern, it would fetch another URL and replace the response with that new content.
It works perfectly for text data (JS, XML...) or binary data (e.g. images), but when it es to video, there is a glitch.
I am using Chrome 41 on OSX.
This is the simplified code of my worker:
self.addEventListener('fetch', function(event) {
var url = event.request.url;
console.log('SW: fetch', url);
if (/\.mp4$/.test(url)) {
url = 'https://vjs.zencdn/v/oceans.mp4';
var options = {
credentials: 'include',
mode: 'no-cors'
};
event.respondWith(fetch(url, options));
}
});
And this is the simplified code in my HTML page:
navigator.serviceWorker.register('sw.js').then(function(reg) {
console.info('ServiceWorker registration successful for', reg.scope);
var video = document.createElement('video');
video.src = '/video.mp4';
video.controls = true;
video.autoplay = true;
video.onerror = function(err) {
console.error('Video load fail', err);
}
video.onload = function(data) {
console.info('Video load success');
}
document.body.appendChild(video);
}).catch(function(err) {
console.error('ServiceWorker registration failed:', err);
});
The first time you load the page, the worker installs, so the video request is not caught, thus failing. But when you reload the page (without cleaning the cache), it is successfully caught, and the worker successfully loads the video (HTTP 200 in its inspector), but for some reason, the main page throws a net::ERR_FAILED
.
And I cannot manually read/stream it, because it es from a different origin, resulting in an "opaque" Response type: http://www.w3/TR/service-workers/#cross-origin-resources
UPDATE: updating to Chrome 42, the error is now HTTP 400 Service Worker Fallback Required (from ServiceWorker)
. Strange thing is that the source code (line 510) indicates that it should only be raised when CORS headers are missing, but here the mode is no-cors
.
1 Answer
Reset to default 7First off, I'd remend trying in the current Chrome Canary, which currently corresponds to release 44.0.2371.0. The developer tooling around service workers continues to improve with each new Chrome release, and it's gotten much better with version 43+ in general.
It doesn't look like opaque Response
objects can be used for the src
of a <video>
element, and I'm assuming that's deliberate. (Opaque Response
s can be used for certain purposes, and I'm afraid I don't have a plete rundown of what will and won't work with an opaque Response
.)
But in any case, you're fortunate in that vjs.zencdn
supports CORS, so you can get away with using the default, CORS-enabled Request
, which will give you a non-opaque Response
.
One thing that you can't do is use credentials: 'include'
in your CORS Request
, because it will lead to a Fetch API cannot load https://vjs.zencdn/v/oceans.mp4. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. error. This doesn't seem like it's an issue with your particular host, since credentials aren't required.
When I switched your code to use event.respondWith(fetch('https://vjs.zencdn/v/oceans.mp4'));
everything worked fine.
本文标签: javascriptHow can I stream a video from a ServiceWorkerStack Overflow
版权声明:本文标题:javascript - How can I stream a video from a ServiceWorker? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744076202a2529397.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论