使用 Safari 对 ArrayBuffer 进行切片并播放

Slice ArrayBuffer with Safari and play it

我需要加载 mp3、切片并使用网络音频播放它,在 firefox 上任意位置播放 mp3 切片并解码工作正常,但在 safari 上出现空值错误。是否存在在 Safari 上对 ArrayBuffer 进行切片的技巧或方法?

player.loadMp3 = function(url, callback) {

var request = new XMLHttpRequest();

request.open('GET', url, true);

request.responseType = 'arraybuffer';

request.onload = function() {

    var mp3slice = request.response.slice(1000,100000);
    player.context.decodeAudioData(mp3slice); // context is webkitAudioContext on safari
    callback();

};

request.send();

};

我需要创建一个具有一些特殊功能的 mp3 播放器:

  1. 时移音乐(喜欢http://codepen.io/eranshapira/pen/mnuoB
  2. 消除音乐之间的差距(我得到了这个切片 ArrayBuffers,然后用 Blob 加入,但仅在 safary/IPAD 中不起作用)。
  3. 跨平台(IPAD 和 android。我正在为此使用 apache cordova)。

解决方案

player.loadMp3 = function(url, callback) {

    console.log("loading " + url);

    var request = new XMLHttpRequest();

    request.open('GET', url, true);

    request.responseType = 'arraybuffer';

    request.onload = function() {

        console.log("loaded");
        console.log("decoding...");

        player.context.decodeAudioData(request.response, function(buffer) {        

            console.log("decoded");

            player.buffer = player.joinAudioBuffers(player.buffer,buffer,2000000);

            player.duration += player.buffer.duration;

            player.time = minsSecs(player.buffer.duration);

            console.log("concatenated");

            callback();

        });



    }, function() {

        alert("decode failure");

    };

    request.send();
};

您显示的代码不应在任何浏览器上运行。一方面,您需要提供一个回调函数来解码音频数据。您还需要在解码数据解码之后对其进行切片,而不是之前对原始mp3编码数据进行切片解码它。某些浏览器可能能够解码 mp3 文件的一部分,但这不是预期的。像这样:

player.loadMp3 = function(url, callback) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';

  request.onload = function() {      
    var mp3slice = request.response.slice(1000,100000);
    player.context.decodeAudioData(mp3slice, function(decoded) {
      var pcmSlice = decoded.slice(1000, 100000);
      callback(pcmSlice);
    });
  };

  request.send();
};

我还没有测试过这段代码。