无法从服务人员播放缓存的音频

Posted

技术标签:

【中文标题】无法从服务人员播放缓存的音频【英文标题】:Cannot play cached audio from service worker 【发布时间】:2016-10-03 09:21:51 【问题描述】:

总结:无法通过 Service Worker 缓存和使用缓存的音频。


尝试:使用服务工作者和缓存 API 缓存相对较小的音频文件 (2-3mb)。这些是通过 html Audio 元素加载/播放的,该元素通常设置一个“范围”标题。

问题:Service Worker 响应整个内容,忽略范围标头,Audio 元素忽略内容并且不播放。

没有 service worker: 服务器服从范围标头,发送部分内容,Audio 元素很高兴并播放音频。

我使用的是 Google Chrome 52。

注意:mnot "Serve range requests from a complete cache entry" 似乎已注意到解决方案,但是否有任何浏览器实现了此功能?或者,有什么解决方法吗??


技术信息

Chrome 终端标准错误:[1:1:0603/164806:ERROR:render_media_log.cc(23)] MediaEvent: PIPELINE_ERROR demuxer: could not open

Chrome 控制台错误:Uncaught (in promise) DOMException: The element has no supported sources.

Chrome 标头(含 SW,2 部分):

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 标头(不含 SW,3 部分!):

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

【问题讨论】:

【参考方案1】:

我使用 IndexedDB 来实现此功能,结果令人印象深刻。您可以使用localForage 将音频文件存储在数据库中,然后通过blob src url 在离线模式下检索它。

request = new XMLHttpRequest();
request.open('GET', audioURL, true);
request.responseType = 'blob';
request.onreadystatechange = function()
if (request.readyState === 4 && request.status === 200)
    localforage.setItem('KeyName', request.response).then(function(savedAudioBlob)  console.log('Saved Blob URL ' + savedAudioBlob); ); 

【讨论】:

【参考方案2】:

查看https://samdutton.github.io/samples/service-worker/prefetch-video/,它通过手动创建范围响应来解决此问题。

解决这个问题的关键在于弄清楚浏览器应该在这里做什么,并在需要时更新 service worker 规范。

【讨论】:

好吧,我正在使用 CORS 音频(来自另一个域),在这种情况下,不可能从请求中读取标头。有解决办法吗?

以上是关于无法从服务人员播放缓存的音频的主要内容,如果未能解决你的问题,请参考以下文章

Gstreamer 无法通过 rtspsrc 播放音频

从 RTSP 服务器渲染音频流

我目前无法停止通过 ajax 调用在服务网页上播放音频

如何使用 HTML5 音频 API 播放从 XMLHTTPRequest 返回的音频

流式传输音频文件并缓存它

Expo AV 音频无法在 iOS/iPhone 上播放