decodeAudioData返回空错误 [英] decodeAudioData returning a null error

查看:306
本文介绍了decodeAudioData返回空错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来这里希望你们这些可爱的人可以帮我解决一些我所遇到的问题。特别是,每次我尝试使用webkitAudioContext的decodeAudioData方法,它总是触发带有空错误的错误处理程序。这是我目前使用的代码:

  var soundArray; 
var context = new webkitAudioContext();
函数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();

$ / code>

此时,它会不断地向控制台记录错误消息,说 err(decodeAudioData)= null ,主要是因为这正是我决定如何记录它的原因。
在任何情况下,任何想法为什么这可能会发生?



我使用Chrome Canary,v20.0.1121.0尝试获取某些内容加工。但是,显然,它不工作!那么,有什么想法我可以做什么?如果需要任何新信息,请告诉我,我会根据需要进行更新。 解决方案

真正的原因是, createBuffer和decodeAudioData现在有一个Bug,并且抛出奇怪的含糊DOM异常12,用于他们通常应该播放的文件。
但是我们应该意识到,这是新的,不断发展的技术,即使对于网络音频api也是如此,因为它发生在我们身上的一个小奇迹。



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


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

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


我讨厌的是,arrayBuffer并没有像它的类型子类那样使用subarray()从不同的偏移量返回不同的视图,而不是slice()返回的整个新数组副本。如果只有webaudio api接受typedarrays作为输入,但不幸的是创建arraybuffer的唯一方法似乎是slice()复制。
幸运的是,通常只需要一两次寻找。



强制Web Audio Api不会被文件挑剔



  node = {}; 
node.url ='usual_mp3_with_tags_or_album_artwork.mp3';

函数syncStream(node){//应该由api本身完成。并希望会。
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那里它复制
delete(node.buf); node.buf = NULL;
node.buf = tmp;
node.sync = i;
返回true;
}
返回false;


函数解码(节点){
尝试{
context.decodeAudioData(node.buf,
函数(解码){
node.source = context.createBufferSource();
node.source.connect(context.destination);
node.source.buffer =已解码;
node.source.noteOn(0);
},
function(){//仅在错误时尝试在帧边界上同步
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();
}


I come here hoping that you lovely folks here on SO can help me out with a bit of a problem that I'm having.

Specifically, every time I attempt to use the decodeAudioData method of a webkitAudioContext, it always triggers the error handler with a null error. This is the code that I'm currently using:

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();
}

At this point, it constantly logs error messages to the console saying err(decodeAudioData) = null, mostly because that was just how I decided to log it. In any case, any idea why this might be going on?

I'm using Chrome Canary, v20.0.1121.0, to try and get something working. But, obviously, it's not working! So, any idea what I might be able to do? If any new information is needed, let me know, and I'll update as necessary.

解决方案

The real reason is that both createBuffer and decodeAudioData right now have a Bug and throw weird vague DOM exception 12 for files they should normally play. But we should be aware that this is new and evolving technology and be thankful even for web audio api as it is now since its small miracle that happened to us.

They are missing stream syncing on header boundary that any reasonable decoder of streaming audio format should start with. And mp3 or many aac/adts files are streaming fileformats. streaming means that you can cut them anywhere or insert append anything (various tags even image artwork) decoder shouldnt care about unknown data. decoder should just seek until he finds header he knows and can decode.

I thrown together this temporary solution that seeks to nearest frame header start and passes data from this offset only.

mp3 or mp2 all start header for every audio frame (every around 200bytes) with 0XFFE and aac(adts) on oxFFF syncword that is there just for this reason. therefore both will sync on 0xFFE. Here is the code I currently use to play previously not played files.

What I hate is that arrayBuffer doesnt have subarray() like its typed childs to return just different view from different offset instead of whole new array copy that slice() returns. if only webaudio api accepted typedarrays as input but unfortunately the only way to create arraybuffer back seems huge slice() copy. thankfully usually only one or two seeks are needed.

Forcing Web Audio Api to not being Picky about files

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();
}

这篇关于decodeAudioData返回空错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆