问题
I have encoded song with Blob. But in FF (38) and Opera it's not work. "Media resource blob: site.com/75f35d17-9aaf-4c7a-a52c-943d62ffd40f could not be decoded."
In FF 37 it's work well. http://jsfiddle.net/mLq0uptw/1/
Help please, how i can play this Blob URL song in FF and Opera?
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// old draw --------------------------------------------------------
//var context = new AudioContext();
var audioBuffer;
var sourceNode;
var analyser;
var javascriptNode;
var actx = new(AudioContext || webkitAudioContext)(), tid,
url = "https://cdn.rawgit.com/epistemex/free-music-for-test-and-demo/master/music/kf_colibris.mp3";
// url = "hello.mp3";
var canvas = document.getElementById('c');
var canvas_context = canvas.getContext('2d');
var gradient = canvas_context.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(1, '#550000');
gradient.addColorStop(0.75, '#ff0000');
gradient.addColorStop(0.25, '#ffff00');
gradient.addColorStop(0, '#ffff00');
canvas_context.fillStyle = gradient;
function playSound(buffer) {
sourceNode.buffer = buffer;
sourceNode.start(0);
}
// log if an error occurs
function onError(e) {
console.log(e);
}
// STEP 1: Load audio file using AJAX ----------------------------------
loadXHR(url, decode);
tid = setInterval(function() {document.querySelector("div").innerHTML += "."}, 500);
function loadXHR(url, callback) {
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "arraybuffer";
xhr.onerror = function() {console.log("Network error.")};
xhr.onload = function() {
if (xhr.status === 200) callback(xhr.response);
else console.log("Loading error:" + xhr.statusText);
};
xhr.send();
} catch (err) {console.log(err.message)}
}
// STEP 2: Decode the audio file ---------------------------------------
function decode(buffer) {
clearInterval(tid);
document.querySelector("div").innerHTML = "Decoding file...";
actx.decodeAudioData(buffer, split);
}
// STEP 3: Split the buffer --------------------------------------------
function split(abuffer) {
document.querySelector("div").innerHTML = "Splitting...";
setTimeout(function() { // to allow DOM to update status-text
// calc number of segments and segment length
var channels = abuffer.numberOfChannels,
duration = abuffer.duration
rate = abuffer.sampleRate,
segmentLen = 10,
count = Math.floor(duration / segmentLen),
offset = 0,
// block = 10 * rate;
block = abuffer.length;
// while(count--) {
var url = URL.createObjectURL(bufferToWave(abuffer, offset, block));
var audio = new Audio(url);
audio.controls = true;
audio.volume = 0.5;
audio.autoplay = true;
//playSound(abuffer);
document.body.appendChild(audio);
var analyser = actx.createAnalyser();
analyser.fftSize = 2048;
// connect the stuff up to eachother/*
var source = actx.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(actx.destination);
freqAnalyser();
function freqAnalyser() {
window.requestAnimFrame(freqAnalyser);
var sum;
var average;
var bar_width;
var scaled_average;
var num_bars = 60;
var data = new Uint8Array(64);
analyser.getByteFrequencyData(data);
//ctx.clearRect(0, 0, 1000, 325);
// clear canvas
canvas_context.clearRect(0, 0, canvas.width, canvas.height);
var bin_size = Math.floor(data.length / num_bars);
for (var i = 0; i < num_bars; i += 1) {
sum = 0;
for (var j = 0; j < bin_size; j += 1) {
sum += data[(i * bin_size) + j];
}
average = sum / bin_size;
bar_width = canvas.width / num_bars;
scaled_average = (average / 256) * canvas.height;
canvas_context.fillRect(i * bar_width, canvas.height, bar_width - 2, - scaled_average);
}
}
//offset += block;
// }
document.querySelector("div").innerHTML = "Ready!";
}, 60)
}
// Convert a audio-buffer segment to a Blob using WAVE representation
function bufferToWave(abuffer, offset, len) {
var numOfChan = abuffer.numberOfChannels,
length = len * numOfChan * 2 + 44,
buffer = new ArrayBuffer(length),
view = new DataView(buffer),
channels = [], i, sample,
pos = 0;
// write WAVE header
setUint32(0x46464952); // "RIFF"
setUint32(length - 8); // file length - 8
setUint32(0x45564157); // "WAVE"
setUint32(0x20746d66); // "fmt " chunk
setUint32(16); // length = 16
setUint16(1); // PCM (uncompressed)
setUint16(numOfChan);
setUint32(abuffer.sampleRate);
setUint32(abuffer.sampleRate * 2 * numOfChan); // avg. bytes/sec
setUint16(numOfChan * 2); // block-align
setUint16(16); // 16-bit (hardcoded in this demo)
setUint32(0x61746164); // "data" - chunk
setUint32(length - pos - 4); // chunk length
// write interleaved data
for(i = 0; i < abuffer.numberOfChannels; i++)
channels.push(abuffer.getChannelData(i));
while(pos < length) {
for(i = 0; i < numOfChan; i++) { // interleave channels
sample = Math.max(-1, Math.min(1, channels[i][offset])); // clamp
sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767)|0; // scale to 16-bit signed int
view.setInt16(pos, sample, true); // update data chunk
pos += 2;
}
offset++ // next source sample
}
// create Blob
return new Blob([buffer], {type: "audio/mpeg"});
function setUint16(data) {
view.setUint16(pos, data, true);
pos += 2;
}
function setUint32(data) {
view.setUint32(pos, data, true);
pos += 4;
}
}
<canvas id="c" width="1000" height="225" style="display: block;"></canvas>
<div>Loading.</div>
来源:https://stackoverflow.com/questions/30348906/ff-and-opera-not-open-encoded-files-with-url-blob