Summary: Unable to cache and use the cached audio via a Service Worker.
Trying to: cache relatively small audio files (2-3mb) using service worker and cache API. These are loaded/played via a HTML Audio element, which usually sets a 'range' header.
Problem: Service worker responds with the whole content, ignoring the range header, and the Audio element ignores the content and does not play.
Without service worker: server obeys the range header, sends partial content, Audio element is happy and plays the audio.
I am using Google Chrome 52.
Note: Solution appears to have been noted by mnot "Serve range requests from a complete cache entry" but has any browser implemented this? Or, is there any workaround??
Technical info
Chrome terminal stderr: [1:1:0603/164806:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open
Chrome console error: Uncaught (in promise) DOMException: The element has no supported sources.
Chrome headers (with SW, 2 parts):
PART#1
GENERAL
Request URL:http://localhost:3333/audio.m4a
Request Method:GET
Status Code:200 OK (from ServiceWorker)
Remote Address:127.0.0.1:3333
RESPONSE
accept-ranges:bytes
connection:keep-alive
content-length:2449048
content-type:audio/x-m4a
date:Fri, 03 Jun 2016 10:14:02 GMT
etag:"56f8f953-255e98"
last-modified:Mon, 28 Mar 2016 09:28:51 GMT
server:nginx
x-content-type-options:nosniff
x-frame-options:SAMEORIGIN
x-xss-protection:1; mode=block
REQUEST
Provisional headers are shown
Accept-Encoding:identity;q=1, *;q=0
Range:bytes=0-
Referer:http://localhost:3333/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.10 Safari/537.36
PART #2
GENERAL
Request URL:http://localhost:3333/audio.m4a
Request Method:GET
Status Code:200 OK (from ServiceWorker)
Remote Address:127.0.0.1:3333
RESPONSE
accept-ranges:bytes
connection:keep-alive
content-length:2449048
content-type:audio/x-m4a
date:Fri, 03 Jun 2016 10:14:02 GMT
etag:"56f8f953-255e98"
last-modified:Mon, 28 Mar 2016 09:28:51 GMT
server:nginx
x-content-type-options:nosniff
x-frame-options:SAMEORIGIN
x-xss-protection:1; mode=block
REQUEST
Provisional headers are shown
Accept-Encoding:identity;q=1, *;q=0
Range:bytes=2392064-
Referer:http://localhost:3333/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.10 Safari/537.36
Chrome headers (without SW, 3 parts!):
PART #1
GENERAL
Request URL:http://localhost:3333/audio.m4a
Request Method:GET
Status Code:206 Partial Content
Remote Address:127.0.0.1:3333
RESPONSE
Connection:keep-alive
Content-Length:2449048
Content-Range:bytes 0-2449047/2449048
Content-Type:audio/x-m4a
Date:Fri, 03 Jun 2016 10:24:32 GMT
ETag:"56f8f953-255e98"
Last-Modified:Mon, 28 Mar 2016 09:28:51 GMT
Server:nginx
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
REQUEST
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Host:localhost:3333
Range:bytes=0-
Referer:http://localhost:3333/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.10 Safari/537.36
PART #2
GENERAL
Request URL:http://localhost:3333/audio.m4a
Request Method:GET
Status Code:206 Partial Content
Remote Address:127.0.0.1:3333
RESPONSE
Connection:keep-alive
Content-Length:56984
Content-Range:bytes 2392064-2449047/2449048
Content-Type:audio/x-m4a
Date:Fri, 03 Jun 2016 10:24:32 GMT
ETag:"56f8f953-255e98"
Last-Modified:Mon, 28 Mar 2016 09:28:51 GMT
Server:nginx
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
REQUEST
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Host:localhost:3333
If-Range:"56f8f953-255e98"
Range:bytes=2392064-2449047
Referer:http://localhost:3333/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.10 Safari/537.36
PART #3
GENERAL
Request URL:http://localhost:3333/audio.m4a
Request Method:GET
Status Code:206 Partial Content
Remote Address:127.0.0.1:3333
RESPONSE
Content-Length:2121368
Content-Range:bytes 327680-2449047/2449048
Content-Type:audio/x-m4a
Date:Fri, 03 Jun 2016 10:24:32 GMT
ETag:"56f8f953-255e98"
Last-Modified:Mon, 28 Mar 2016 09:28:51 GMT
Server:nginx
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
REQUEST
Provisional headers are shown
Accept-Encoding:identity;q=1, *;q=0
Range:bytes=327680-
Referer:http://localhost:3333/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.10 Safari/537.36
Using a Service worker you can easily set an app up to use cached assets first, thus providing a default experience even when offline, before then getting more data from the network (commonly known as Offline First).
For google chrome users:Go to Developer Tools (ctrl shift i/cmd opt i) or right-click on any page element, then click Inspect. Go to the Application tab and then click on service workers in the left bar. It will list all the registered service workers. Click on unregister to disable that particular service worker.
To bypass the service worker, set ngsw-bypass as a request header, or as a query parameter. The value of the header or query parameter is ignored and can be empty or omitted.
Service worker caching strategies and use cases #It's preferable to serve the fresh content. However if the network fails or is unstable, it's acceptable to serve slightly old content. It's okay to serve cached content right away, but updated cached content should be used in the future.
Check out https://samdutton.github.io/samples/service-worker/prefetch-video/ which works around this issue by manually created ranged responses.
Fixing this is gated on figuring out what browsers should be doing here, and updating the service worker spec if needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With