Javascript html 音频元素播放错误处理(既没有结束也没有显示任何错误)

Javascript html audio element play error handling (neither ends nor shows any error)

计划目的和描述

我已经创建了一个 javascript 音频控制器,它 运行 在我的 Windows 计算机(出于测试原因)和我的 android 手机上的浏览器中非常完美phone。它能够

为了实现最后一点,我必须监听 audio.onended 事件,以便等待下一个声音的开始,直到上一个声音播放完毕。

问题描述

javascript 音频控制器是移动应用程序的一部分,因此它必须 运行 在 mobile/smartphone 浏览器上。当我 运行 在 iPhone Safari 中使用相同的应用程序时,会播放一些声音,但随后不会播放某些声音。为了解决这个问题,我添加了一个 onerror 事件侦听器,但既不是 onended 处理程序,也不是

代码

   async playNwait(audio) { // plays sound and waits until it has finished
      return new Promise ((resolve) => {
         audio.onerror = (event) => {
            log('Play Error: ' + audio.error.code);
            log('Play Error: ' + audio.error.message);
            log('Play Error: ' + event.currentTarget.error.code);
            log('Play Error: ' + event.currentTarget.error.message);
            reject('Audio failed');
         };
         audio.onended = (event) => {
            log('      playNwait ended');
            resolve('Audio ended');
         };
         log('      playNwait started');
         log(audio.src);
         audio.addEventListener("error", function(e) {
            log("Playback error: " + e.currentTarget.error.code);
            var prop, props='\nEvent properties are: ';
            var o = e.currentTarget.error;
            for (prop in o) {
                props += prop+'='+o[prop]+' ';
             }
            log(props);
            reject('Audio failed');
         });         
         audio.play();
      });
   }

函数日志调用具有相同参数的 console.log 函数,并且还通过 API 将值发送到服务器,并在数据库中记录 table,为了分析移动浏览器的日志条目。

我知道我有两个具有相同目的的错误处理程序。 None 起火。

日志条目

为了便于比较,以下是 Firefox 在 Andriod 和 Safari 在 iOS 上生成的相关日志条目:

Android

上的 Firefox
"Playing 4: 60_sechzig"     2021-05-28 23:40:28
"      playNwait started"   2021-05-28 23:40:28
"data:audio\/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPA..."  2021-05-28 23:40:28
"      playNwait ended"     2021-05-28 23:40:29
"Played 4"  2021-05-28 23:40:29

iPhone 野生动物园

"Playing 4: 60_sechzig"     2021-05-28 22:21:13
"      playNwait started"   2021-05-28 22:21:13
"data:audio\/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPA..."  2021-05-28 22:21:13

... 仅此而已 - onended 和一个错误处理程序都不会触发。此外,不会播放更多的声音,因为应用程序错误地认为之前的声音还没有播放完。 (它没有开始播放。)

4只是“播放列表”中声音的编号。

问题

如何让 onerror 事件处理程序工作?我该如何进一步解决这个问题?

非常感谢任何帮助。

已识别问题:iOS Safari 上的音频播放功能因 NotAllowedError 失败:“当前上下文中的用户代理或平台不允许该请求,可能是因为用户拒绝了许可。 “

这是我更新的报告错误的函数(并添加了一些调试):

   async playNwait(audio) { // plays sound an wait until it has finished
      return new Promise (async (resolve, reject) => {
         audio.onerror = (event) => {
            log('Play Error: ' + audio.error.code);
            log('Play Error: ' + audio.error.message);
            log('Play Error: ' + event.currentTarget.error.code);
            log('Play Error: ' + event.currentTarget.error.message);
            reject('Audio failed');
         };
         audio.abort = (event) => {
            log('      playNwait abort');
         };
         audio.loadstart = (event) => {
            log('      playNwait loadstart');
         };
         audio.onplay = (event) => {
            log('      playNwait playing');
         };
         audio.onended = (event) => {
            log('      playNwait ended');
            resolve('Audio ended');
         };
         log('      playNwait started');
         log(audio.src);
         audio.addEventListener("error", function(e) {
            log("Playback error: " + e.currentTarget.error.code);
            var prop, props='\nEvent properties are: ';
            var o = e.currentTarget.error;
            for (prop in o) {
                props += prop+'='+o[prop]+' ';
             }
            log(props);
            reject('Audio failed');
         });         
         try {
            await audio.play();
         } catch (err) {
            error ('Media play error: ' + err.name + ' - ' + err.message);
         }
      });
   }

我知道 iOS Safari 会在音频未被用户交互初始化时阻止播放音频。我知道我过去有一个成功的解决方案,那就是在用户交互时加载音频文件。

但是,这是一个不同的问题,这里的这个问题已经解决:错误处理程序从不触发,因为播放方法已经失败。