FF and Opera not open encoded files with “URL Blob”

有些话、适合烂在心里 提交于 2019-11-28 12:23:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!