我有一个专职服务人员,并且已缓存声音(mp3文件),以便可以离线播放它们。这是ngsw-config-json
:
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js",
"/*.svg",
"/*.eot",
"/*.woff",
"/*.woff2",
"/*.tff"
]
}
}, {
"name": "assets",
"installMode": "prefetch",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/sounds/character1/**",
"/assets/sounds/character2/**"
]
}
}]
}
在我的网络应用中,声音的播放方式如下:
let audioLink = `/assets/sounds/${character}/${soundURL}`;
let player = new Audio(audioLink);
player.play()
该网站离线运行。 HTML,CSS,JS,JSON文件均已缓存。但是声音没有播放(当我尝试播放时,出现上面显示的错误)。
在Chrome开发者工具> 应用程序> 缓存中,我可以看到一些声音(路径),但不是全部。但是其中没有都可以脱机工作。
有时会出现这些错误:
GET "path/to/file" net::ERR_ABORTED 504 (Gateway Timeout)
Uncaught (in promise) DOMException
Failed to load resource: net::ERR_INTERNET_DISCONNECTED
有时它还表示manifest.json
存在问题,但是没有问题,因为它在线时显示在开发人员工具的清单部分中。
此问题是否有解决方法?这不是Chrome的错误,因为我在Safari和Firefox中也看到了相同的行为。我知道新的chrome版本中有一个错误,由于这个错误,favicon.ico
不会脱机显示
不确定是否有帮助,但是here是指向托管Web应用程序的链接。如果您在Chrome开发者工具中看到“网络”标签,则可以看到mp3文件正在“下载”,但它们不能离线播放。
生成用于生产(ng build --prod --base-href="/"
的网站后,我调查了ngsw.json
,这就是我所看到的(删除了一些行):
{
"name": "assets",
"installMode": "prefetch",
"updateMode": "prefetch",
"urls": [
"/assets/sounds/character1/sound one.mp3",
"/assets/sounds/character1/sound two.mp3",
"/assets/sounds/character2/sound three.mp3"
"/assets/sounds/character2/sound four.mp3"
],
"patterns": []
}
Here是完整生成的ngsw.json
。一切都已设置为预缓存,而不是延迟缓存。
所有这些资产URL也在"hashTable"
对象中。我还看到它们是在chrome开发人员工具(开发人员工具>网络)中下载的,但我只在应用程序缓存部分中看到了其中的某些部分(也许是总共150中的前20-30)。
我在这里做错了什么?这可能是Angular 7错误吗?我也看到过其他关于类似问题的其他StackOverflow和Reddit问题。
我尝试过的事情正在改变
let audioLink = `/assets/sounds/${character}/${soundURL}`;
到
let audioLink = `assets/sounds/${character}/${soundURL}`;
(开始时删除了斜杠),但这没有什么不同。
我完全确定所有声音文件路径都是正确的,因为当网站在线运行时绝对没有错误。
除上述内容外,我尝试手动更改所有URL,并在应该有空格的地方插入%20
。例如,将"/assets/sounds/character1/sound one.mp3"
更改为"/assets/sounds/character1/sound%20one.mp3"
,但这也不起作用。
我注意到的一件事是,如果您是第一次访问该网站,并等待所有声音下载,然后不重要,然后关闭Internet连接并尝试该站点,则所有声音都会起作用。但是只有一段时间(通常在10-15分钟左右),它们才会停止工作。我已经在Chrome,Chrome Android,Firefox,Safari和IOS Safari上进行了测试。
编辑:根据某人的建议,我尝试更改
{
"name": "assets",
"installMode": "prefetch",
"updateMode": "prefetch",
"urls": [
"/assets/sounds/character1/sound one.mp3",
"/assets/sounds/character1/sound two.mp3",
"/assets/sounds/character2/sound three.mp3"
"/assets/sounds/character2/sound four.mp3"
],
"patterns": []
}
到
{
"name": "assets",
"installMode": "prefetch",
"updateMode": "prefetch",
"urls": [
"/assets/sounds/**"
],
"patterns": []
}
,但是仍然存在相同的问题:声音被离线缓存大约10至15分钟,之后它们便无法离线播放。我只能在Chrome和Chrome Android中对此进行测试。
答案 0 :(得分:3)
我尝试制作一个演示来隔离错误,并且似乎可以正常工作。在应用程序缓存中发现了一些奇怪的网址:
不确定是引起问题的原因。您已经提到,使设备脱机后声音会起作用,我想这是浏览器缓存而不是脱机缓存。 当我尝试刷新页面时,声音永远无法正常工作。我的猜测是ngsw的配置或ngsw缓存文件的方式与Audio类不兼容。
您可以通过先使用@angular/common/http
来将blob传递到Audio中来测试它是否有效。我在想这是因为音频文件似乎位于不同的缓存目录中(请参见屏幕截图)。出于某些原因,css / js文件的存储方式似乎有所不同,音频文件只能(离线)访问角度文件。
发布评论的时间太长
答案 1 :(得分:2)
我在@codeninja的帮助下找到了问题的答案。
首先,audioLink
必须是声音的直接链接。我将网站托管在Github上,因此链接看起来像这样:
let url = `sounds/path_to_sound.mp3`
let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;
第二,我们不能仅将sound.play()
与Audio()
方法一起使用,我们必须使用HttpClient
来检索音频。我不确定为什么会这样,但是codeninja建议ngsw
缓存文件的方式与Audio
类不兼容。我不确定这是否成立,但是我发现离线时必须使用HttpClient
来检索音频Blob(如下所示)。如果不是,则会出现response not Ok
错误。即使我给了直接链接https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/direct.mp3
,它也会抛出相同的错误。
总而言之,代码看起来像这样:
首先有一个getSound()
函数:
getSound(url) {
return this.http.get(url, {responseType: 'blob'});
}
然后在另一个函数(playSound(url)
)中,我们有这个功能:
playSound(url) {
let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;
this.getSound(audioLink)
.subscribe(data => {
console.log(data);
// data is an audio blob
let url = URL.createObjectURL(data);
let sound = document.createElement('audio');
sound.src = url;
sound.play();
})
}
此外,我还必须更改我的ngsw-config.json
。我只更改了“资产”部分,因此我将向您展示:
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
],
"urls": [
"https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/**"
]
}
}
我也无法使其与“预取”一起使用。尽管现在缓存的声音可以脱机播放,但它们只会在以前播放过的情况下播放,因为它设置为“惰性”。
我在Chrome,Chrome Android和Firefox上测试了该解决方案,并且运行良好。