Нарезать ArrayBuffer с Safari и играть в него
Мне нужно загрузить mp3, нарезать и воспроизвести его с помощью веб-аудио, на Firefox срезать mp3 в любом месте и декодировать нормально, но в сафари возникает ошибка с нулевым значением. Есть хитрость или способ нарезать ArrayBuffer на Safari?
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-плеер с некоторыми особенностями:
- Время смены музыки (например, http://codepen.io/eranshapira/pen/mnuoB)
- Устранить разрыв между музыкой (я получил этот ArrayBuffers среза и затем присоединяюсь с Blob, но только в Safary/IPAD не работает).
- Кроссплатформенность (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();
};
1 ответ
Решение
Код, который вы показали, не должен работать ни в одном браузере. Во-первых, вам нужно предоставить функцию обратного вызова для decodeAudioData. Вам также необходимо разрезать декодированные данные после декодирования, а не необработанные данные в формате 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();
};
Я не проверял этот код.