【问题标题】:audio Blob not working in IOS / Safari音频 Blob 在 IOS / Safari 中不起作用
【发布时间】:2017-09-23 01:17:17
【问题描述】:

我正在录制音频,将其作为 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 的检查员进一步了解,我发现了这一点:

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

仪式方向的指导会很有帮助!

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

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

【问题讨论】:

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


【解决方案1】:

对我来说,解决方案是将源元素插入到音频元素中,并使用 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()

【讨论】:

    【解决方案2】:

    我无法找到使用音频元素的解决方案,但是 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 上可能仍然存在问题,因为任何音频/视频都必须由用户操作触发。

    【讨论】:

      【解决方案3】:

      这周我遇到了类似的问题。我在 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 进行了测试,效果很好。

      【讨论】:

      • 这个问题有点不同。我能够将数据发送回服务器,但将其发送给其他连接的客户端时,他们无法在 iOS 和 safari 上接收数据
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 2013-07-27
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多