decodeAudioData - 无法解码音频数据

时间:2017-03-11 18:39:59

标签: javascript html5 web-audio

我正在使用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();
        }
      })
    },

1 个答案:

答案 0 :(得分:2)

直到最近,decodeAudioData无法解码Chrome MediaRecorder的结果。尝试Chrome金丝雀或测试版,看看是否已修复。如果您仍然遇到问题,请提供更完整(但简单)的示例,了解哪些内容无效。