音频Blob无法在IOS / Safari中运行

时间:2017-04-25 20:43:38

标签: ios node.js socket.io blob html5-audio

我正在录制音频,将其作为blob发送到nodejs服务器。然后,nodejs服务器将其发送给当前未记录的所有连接用户。

发送blob:

mediaRecorder.onstop = function(e) {
  var blob = new Blob(this.chunks, { 'type' : 'audio/ogg; codecs=opus' });
  socket.emit('radio', blob);
};

服务器接收blob:

socket.on('radio', function(blob) {
  socket.broadcast.emit('voice', blob);
});

收听blob的听众:

socket.on('voice', function(arrayBuffer) {
  var blob = new Blob([arrayBuffer], { 'type' : 'audio/ogg; codecs=opus' });
  var audio = document.getElementById('audio');
  audio.src = window.URL.createObjectURL(blob);
  audio.play();
});

这适用于除safari和任何ios设备之外的所有浏览器/设备。在safari的检查员的帮助下,我发现了这一点:

1st blob object returned 2nd blob object returned 3rd blob object returned

safari是否需要在其标题中使用其他内容才能正确解释blob对象?我已经研究过接受过的音频类型,试过aac / mp3 / ogg没有任何成功。在进一步阅读后,我听说过在safari和IOS中存在流blob音频/视频数据的错误,尽管我不太清楚任何细节。

仪式方向的指导非常有帮助!

编辑:接收blob中的这一行audio.src = window.URL.createObjectURL(blob);看起来是造成blob错误的原因(我链接的图片)

编辑2:我试图查看使用blob以外的其他格式是否有效,选择使用base64编码的字符串。看起来这适用于除IOS和Safari之外的所有设备和浏览器。我得到的印象是它与IOS如何解释/加载数据有关...

3 个答案:

答案 0 :(得分:2)

对我来说,解决方案是将一个源元素插入audio元素,并使用sourceElement.src属性来引用blob。我甚至不需要将音频元素附加到DOM。以下示例,希望它可以帮助某人。

var audioElement = document.createElement('audio')
var sourceElement = document.createElement('source')

audioElement.appendChild(sourceElement)

sourceElement.src = '<your blob url>'
sourceElement.type = 'audio/mp3' // or whatever

audioElement.load()

audioElement.play()

答案 1 :(得分:1)

这周我遇到了类似的问题。我正在Safari上录制音频,并且音频Blob正在生成。但是,当我尝试将Blob发送到服务器时,没有数据到达那里。下面的解决方案使用File Reader读取blob以将其转换为base64,然后将其发送到服务器。这是对我有用的东西:

      const reader = new FileReader();
      reader.readAsDataURL(audioBlob);
      reader.onloadend = () => {
      const base64data = reader.result;

      const audioName = uuid.v4() + '.mp3';
      this.http.post(this.app.cloudStorageEndpoint + '/audios/local?audioName=' + audioName, base64data , header).subscribe(
        res => { resolve(audioName); },
        err => { reject(err); }
      );
  };

我已经在iPad和iPhone上使用Safari 12进行了测试,并且效果很好。

答案 2 :(得分:0)

我无法使用音频元素找到解决方案,但Web Audio Api似乎可以解决问题:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API

    var audioContext = new (window.AudioContext || window.webkitAudioContext);
    socket.on('voice', function(arrayBuffer) {
      audioContext.decodeAudioData(arrayBuffer, audioData => {
        var source = audioContext.createBufferSource();
        source.buffer = audioData;
        source.connect(audioContext.destination);
        source.start()
    });

您可能仍然在iOS上遇到问题,因为任何音频/视频都必须由用户操作触发。