【问题标题】:decodeAudioData - Unable to decode audio datadecodeAudioData - 无法解码音频数据
【发布时间】:2017-03-11 18:39:58
【问题描述】:

我正在使用 AudioContext 的 decodeAudioData 方法在 Chrome、Firefox 和 Opera 中播放音频。所有浏览器都成功解码和播放使用 Firefox 录制的音频。但是当使用 Chrome 或 Opera 录制音频时,只有 Firefox 成功解码并播放。在 Chrome 或 Opera 中解码音频时出现以下错误:

Uncaught (in promise) DOMException: Unable to decode audio data.    

我尝试实施此处提到的 Ladislav Nevery 建议的修复: decodeAudioData returning a null error

已实现的代码成功执行了他的建议(遍历缓冲区以在音频流中查找起点),但在 Chrome 中对 Firefox 录制的音频进行解码仍然失败。

知道解码失败的原因吗?

    function syncStream(node){ // should be done by api itself. and hopefully will.
      var buf8 = new Uint8Array(node.buf);
      buf8.indexOf = Array.prototype.indexOf;
      var i=node.sync, b=buf8;
      while(1) {
        node.retry++;
        i=b.indexOf(0xFF,i); if(i==-1 || (b[i+1] & 0xE0 == 0xE0 )) break;
        i++;
      }
      if(i!=-1) {
        var tmp=node.buf.slice(i); //carefull there it returns copy
        delete(node.buf); node.buf=null;
        node.buf=tmp;
        node.sync=i;
        return true;
      }
      return false;
    }

    export function loadAudio(deckId) {
      store.audioPlayerDomain.audioLoading = true;
      let activeRecord = getActiveRecordByDeckId(deckId);
      let path = `${deckId}/${activeRecord.id}`;
      let context = getAudioContext();
      let processFn = function(node){
        return context.decodeAudioData(node.buf, function (decoded) {
            return decoded;
          },
          function(){ // only on error attempt to sync on frame boundary
            if(syncStream(node)){
              return processFn(node);
            };
          });
      };
      return AudioPlayerWebAPI.default.getAudio(path, context)
        .then((buffer) => {
          let node = {};
          node.buf=buffer;
          node.sync=0;
          node.retry=0;
          return processFn(node);
        }).then(function(decodedData) {
          store.audioPlayerDomain.audio = decodedData;
          store.audioPlayerDomain.audioLoading = false;
          return true;
        });
    }

    ....

    getAudio(path, context) {
    return fetch(`/api/public/audio/${path}`)
      .then(processResponse)
      .then(function(response) {
        if(response.message && response.message === 'non-existent'){
          return null;
        }else{
          return response.arrayBuffer();
        }
      })
    },

【问题讨论】:

  • 为什么不使用.decodeAudioData().then() 而不是尝试从.decodeAudioData(callbackFunction) 的回调函数版本返回一个值? callbackFunction 是异步的,是吗?
  • 难道不值得从相反的方向解决这个问题,并弄清楚为什么 Chrome 以不同的格式记录以及如何改变它?您可能想使用ffprobe 检查您的文件格式。您还可以使用ffmpeg 或基于云的解决方案(有几个)对您的文件进行转码,以确保它始终可以播放。

标签: javascript html web-audio-api


【解决方案1】:

直到最近,decodeAudioData 无法解码 Chrome 的 MediaRecorder 的结果。尝试 Chrome canary 或 beta 以查看是否已修复。如果您仍有问题,请提供一个更完整(但更简单)的示例来说明什么不起作用。

【讨论】:

  • 我也遇到了同样的问题,但我刚刚下载了Chrome Canary,它运行正常,没有出现错误。
猜你喜欢
  • 2021-02-14
  • 2013-11-11
  • 2017-06-09
  • 1970-01-01
  • 2013-05-05
  • 2017-05-16
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多