如何使用Angular $ http加载AudioBuffer?

时间:2015-12-01 11:53:57

标签: angularjs web-audio

我开始使用Web Audio Api进行一些实验,希望了解如何在AngularJS中使用它。

我试过的其他Web Audio似乎在Angular中工作,比如创建一个Web音频正弦波等,但我只是不确定以角度加载音频的最佳方法,如果我想能够使用Web Audio API操作它

我天真地尝试将一些函数直接放入一个看似不对的AngularJS控制器 - 下面的代码。

在Chrome开发工具网络标签中,我可以看到应加载的test.mp3通知'无法加载响应数据'。但是文件的路径是正确的,如果我在开发工具中点击它,文件就会打开并开始播放。

非常感谢任何帮助

// Controller and attempt to load audio
(function () {
'use strict';

angular
    .module('app')
    .controller('mvMainCtrl', mvMainCtrl);

mvMainCtrl.$inject = ['$resource', '$scope', '$http' ];

function mvMainCtrl($scope, $http, $resource) {


var ctx; //audio context 
var buf; //audio buffer 

//init the sound system 
function init() { 
  console.log("in init"); 
try { 
    ctx = new AudioContext(); 
    loadFile(); 
} catch(e) { 
    alert('you need webaudio support'); 
} 
} 


function loadFile() { 
  var req = new XMLHttpRequest(); 
  req.open("GET","/app/main/sounds/test.mp3",true); 
req.responseType = "arraybuffer"; 
req.onload = function() { 
    //decode the loaded data 
    ctx.decodeAudioData(req.response, function(buffer) { 
        buf = buffer; 
        play(); 
    }); 
}; 
req.send(); 
}


  loadFile();


 function playback() {
    var playSound = ctx.createBufferSource();
    playSound.buffer = buf;
    playSound.connect(ctx.destination);
    playSound.start(audioContext.currentTime);
 }


  playback();



 }
})();

2 个答案:

答案 0 :(得分:1)

这是一个BufferLoader的实现,可用于加载声音文件数组:

// BufferLoader
function BufferLoader(context, urlList, callback) {
  this.context = context;
  this.urlList = urlList;
  this.onload = callback;
  this.bufferList = new Array();
  this.loadCount = 0;
}

BufferLoader.prototype.loadBuffer = function(url, index) {
  // Load buffer asynchronously
  var request = new XMLHttpRequest();
  request.open("GET", url, true);
  request.responseType = "arraybuffer";

  var loader = this;

  request.onload = function() {
    // Asynchronously decode the audio file data in request.response
    loader.context.decodeAudioData(
      request.response,
      function(buffer) {
        if (!buffer) {
          alert('error decoding file data: ' + url);
          return;
        }
        loader.bufferList[index] = buffer;
        if (++loader.loadCount == loader.urlList.length)
          loader.onload(loader.bufferList);
      },
      function(error) {
        console.error('decodeAudioData error', error);
      }
    );
  }

  request.onerror = function() {
    alert('BufferLoader: XHR error');
  }

  request.send();
}

BufferLoader.prototype.load = function() {
  for (var i = 0; i < this.urlList.length; ++i)
  this.loadBuffer(this.urlList[i], i);
}

如何使用它来加载声音:

var sounds = ["assets/test.mp3", "test2.mp3"]
var context = window.AudioContext || window.webkitAudioContext || window.MozAudioContext || window.mozAudioContext;

var loader = new BufferLoader(context, sounds, onComplete);

var audioBuffers;
function onComplete(bufferList){
  console.log("Sounds loaded!");
  audioBuffers = bufferList;
}

function playSound(i){
  // create buffer source node which is used to play a sound one time
  var bufferSourceNode = context.createBufferSource(); 
  // set buffer to one of the loaded sounds;
  bufferSourceNode.buffer = audioBuffers[i];
  // connect to output
  bufferSourceNode.connect(context.destination);
  // play the sound
  bufferSourceNode.start()
}

现在播放你必须打电话的声音:

playSound(0); // play first sound in array of loaded sounds

在您的示例中,我看不到您在play()中调用的decodeAudioData函数的定义位置。您可能想要致电playback()。你也可以在尚未加载声音的控制器初始化时调用播放,这是你不应该做的。

答案 1 :(得分:1)

我遇到了同样的问题,在这个问题上花了几个小时后,我最终找到了一种方法让它发挥作用:

承诺风格:

$http({
    method: 'GET',
    url: url,
    responseType: 'arraybuffer'
}).then(function(response) {
    audioContext.decodeAudioData(response.data, function(buffer) {
        mainBuffer = buffer
    }, function(err) {
        console.log(err)
    })
})

标准格式:

$http({
    method: 'GET',
    url: url,
    responseType: 'arraybuffer'         
}).success(function(data) {
    audioContext.decodeAudioData(data, function(buffer) {
        mainBuffer = buffer
    }, function(err) {
        console.log(err)
    })
})

使用XMLHttpRequest()时,文件已损坏, responseType attribut应指定为 arraybuffer

相关问题