【问题标题】:decodeAudioData returning a null errordecodeAudioData 返回空错误
【发布时间】:2012-05-09 01:40:16
【问题描述】:

我来到这里希望你们可爱的人在这里可以帮助我解决我遇到的一些问题。

具体来说,每次我尝试使用 webkitAudioContext 的 decodeAudioData 方法时,它总是会触发带有 null 错误的错误处理程序。这是我目前正在使用的代码:

var soundArray;
var context = new webkitAudioContext();
function loadSound(soundName) {
    var request = new XMLHttpRequest();
    request.open('GET',soundName);
    request.responseType = 'arraybuffer';
    request.onload = function() {
            context.decodeAudioData(this.response, function(buf) {
                sounds[soundName] = buf;
            },function(err) { console.log("err(decodeAudioData): "+err); });
    }
    request.send();
}

此时,它会不断将错误消息记录到控制台,说err(decodeAudioData) = null,主要是因为我决定记录它的方式。 无论如何,知道为什么会这样吗?

我正在使用 Chrome Canary v20.0.1121.0 来尝试让某些东西正常工作。但是,显然,它不起作用!那么,知道我能做什么吗?如果需要任何新信息,请告诉我,我会根据需要进行更新。

【问题讨论】:

  • 它是否适用于其他音频源?根据我的经验,并非所有音频文件都可以为 API 解码。你可能想爱一个 new.crbug.com
  • 我用过OGG、MP3和WAV,都无济于事。我读过一次提交的 chrome 错误,它可能是 chrome 不喜欢播放只有一两秒长的音频文件,但我有第二个项目正在运行,以使用拖放构建基于 Web 的音频播放器,并且完整3-4 分钟的歌曲也失败了。我会看看我能做些什么来提交一个错误报告,谢谢你的建议!
  • 此问题已修复,请忽略此问题
  • 您能否提供有关如何修复 Scott 的详细信息?

标签: javascript html google-chrome webkit web-audio-api


【解决方案1】:

我在 Chrome 19 中使用 webkitAudioContext。今天我升级到 Chrome 20,我遇到了和你一样的问题。

我获取了另一个 MP3 文件,它又可以工作了。这两个文件的唯一区别是嵌入了错误的 MP3 文件的封面。

我取下了盖子,它又可以工作了。

【讨论】:

    【解决方案2】:

    真正的原因是 createBuffer 和 decodeAudioData 现在都有一个错误,并为它们通常应该播放的文件抛出奇怪的模糊 DOM 异常 12。 但我们应该意识到,这是一项新的、不断发展的技术,即使是网络音频 API,也应该感谢它,因为它发生在我们身上的小奇迹。

    他们缺少任何合理的流音频格式解码器都应该开始的标题边界上的流同步。 mp3 或许多 aac/adts 文件是流文件格式。流媒体意味着您可以在任何地方剪切它们或插入附加任何东西(各种标签甚至图像艺术品)解码器不应该关心未知数据。解码器应该一直寻找,直到找到他知道并且可以解码的标头。

    我将这个临时解决方案放在一起,它会寻找最近的帧头开始并仅从这个偏移量传递数据。

    mp3 或 mp2 都是每个音频帧(每 200 字节左右)的起始标头,oxFFF 同步字上的 0XFFE 和 aac(adts) 正是出于这个原因。因此两者都将在 0xFFE 上同步。 这是我目前用来播放以前没有播放过的文件的代码。

    我讨厌的是 arrayBuffer 没有 subarray() 像它的类型化的孩子一样从不同的偏移量返回不同的视图,而不是 slice() 返回的全新数组副本。如果只有 webaudio api 接受 typedarrays 作为输入,但不幸的是,创建 arraybuffer 的唯一方法似乎是巨大的 slice() 副本。 谢天谢地,通常只需要一两次搜索。

    强制 Web Audio Api 对文件不挑剔

    node={};
    node.url='usual_mp3_with_tags_or_album_artwork.mp3';
    
    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;
    }
    
    function decode(node) {
        try{
            context.decodeAudioData(node.buf,
            function(decoded){
                node.source  = context.createBufferSource();
                node.source.connect(context.destination);
                node.source.buffer=decoded; 
                node.source.noteOn(0);
            },
            function(){ // only on error attempt to sync on frame boundary
                if(syncStream(node)) decode(node);
            });
        } catch(e) {
            log('decode exception',e.message);
        }
    }
    
    function playSound(node) { 
        node.xhr = new XMLHttpRequest();
        node.xhr.onload=function(){  
            node.buf=node.xhr.response;
            node.sync=0;
            node.retry=0;
            decode(node);
        }
        node.xhr.open("GET", node.url, true); 
        node.xhr.responseType = "arraybuffer"; 
        node.xhr.send();
    }
    

    【讨论】:

    • 遇到了这个。非常感谢拉迪斯拉夫。显然这个错误在 iOS 8.3 中仍然普遍存在
    猜你喜欢
    • 2021-06-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    相关资源
    最近更新 更多