Подтвердить что ты не робот

DecodeAudioData возвращает нулевую ошибку

Я прихожу сюда, надеясь, что вы, прекрасные люди, здесь, на SO, могут помочь мне с некоторой проблемой, которую я испытываю.

В частности, каждый раз, когда я пытаюсь использовать метод decodeAudioData для webkitAudioContext, он всегда вызывает обработчик ошибок с нулевой ошибкой. Это код, который я использую сейчас:

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, чтобы попробовать что-то работать. Но, очевидно, это не работает! Итак, любая идея, что я мог бы сделать? Если какая-либо новая информация необходима, сообщите мне, и я при необходимости обновлю.

4b9b3361

Ответ 1

Настоящая причина заключается в том, что и createBuffer, и decodeAudioData теперь имеют ошибку и бросают странное неопределенное исключение DOM 12 для файлов, которые они обычно должны играть. Но мы должны знать, что это новая и развивающаяся технология, и быть благодарными даже за веб-аудио api, поскольку это происходит со времен своего небольшого чуда, который произошел с нами.

Им не хватает синхронизации потока на границе заголовка, с которой должен начинаться любой разумный декодер потокового аудиоформата. И mp3 или многие файлы aac/adts являются потоковыми файловыми форматами. потоковая передача означает, что вы можете вырезать их в любом месте или вставлять что-либо добавить (различные теги даже изображения) декодер не должен заботиться о неизвестных данных. декодер должен просто искать, пока не найдет заголовок, который он знает, и может декодировать.

Я собрал это временное решение, которое ищет ближайший заголовок кадра и передает данные только из этого смещения.

mp3 или mp2 все начальный заголовок для каждого звукового фрейма (каждый около 200 байт) с 0XFFE и aac (adts) на syncword oxFFF, который есть только по этой причине. поэтому оба будут синхронизироваться на 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();
}

Ответ 2

Я использовал webkitAudioContext с Chrome 19. Сегодня я обновился до Chrome 20, и у меня такая же проблема, как и у вас.

Я взял другой файл MP3, и он снова работает. Единственное различие между этими двумя файлами - это обложка, встроенная в неправильный файл MP3.

Я снял крышку, и она снова работает.

Ответ 3

У меня такая же проблема, как и у iPhone 4 под управлением iOS7. Пробовал это решение и до сих пор ничего. Является ли это самим файлом или он не имеет ничего общего с загруженным массивом буферов?