【问题标题】:Javascript html audio element play error handling (neither ends nor shows any error)Javascript html 音频元素播放错误处理(既不结束也不显示任何错误)
【发布时间】:2021-08-17 02:50:20
【问题描述】:

项目目的和说明

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

  • 将 base64 编码的声音加载到“声音池”中
  • 将池中的某些声音添加到“播放列表”中
  • 按添加顺序播放列表中的声音,一个接一个

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

问题描述

javascript 音频控制器是移动应用程序的一部分,因此它必须在移动/智能手机浏览器上运行。当我在 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();
      });
   }

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

我知道我有两个具有相同目的的错误处理程序。他们都没有开火。

日志条目

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

Android 上的火狐

"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 Safari

"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 事件处理程序正常工作?我该如何进一步解决这个问题?

非常感谢任何帮助。

【问题讨论】:

    标签: javascript audio error-handling


    【解决方案1】:

    已识别的问题: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 在未由用户交互初始化时会阻止播放音频。我知道我过去有一个成功的解决方案,即在用户交互时加载音频文件。

    然而,这是一个不同的问题,这个问题在这里得到解决和解决:错误处理程序永远不会触发,因为播放方法已经失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 2016-03-15
      • 2022-08-23
      • 2021-11-22
      • 2014-11-23
      • 1970-01-01
      相关资源
      最近更新 更多