【问题标题】:Failed to set the 'buffer' property on 'AudioBufferSourceNode': Failed to convert value to 'AudioBuffer'无法在“AudioBufferSourceNode”上设置“buffer”属性:无法将值转换为“AudioBuffer”
【发布时间】:2021-10-28 03:57:46
【问题描述】:

我正在尝试使用 socket.io 和 mediastream 在客户端之间实时发送音频。我能够记录,将该数据发送到服务器,然后发送到不同的客户端。但是当我尝试将 arraybuffers 转换为 audiobuffers 然后将它们连接到音频输出设备时,我收到错误消息

Failed to set the 'buffer' property on 'AudioBufferSourceNode': Failed to convert value to 'AudioBuffer'.

我不明白为什么会这样。这是我的一些代码。

客户端

const socket = io();
const audioCtx = new AudioContext()
const audioC = new AudioContext()

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia

    if (navigator.getUserMedia) {
      console.log('getUserMedia supported.')

      navigator.getUserMedia(
        { audio: true },
        stream => {
          const source = audioCtx.createMediaStreamSource(stream)
          const processor = audioCtx.createScriptProcessor(2048, 1, 1)

          source.connect(processor)
          processor.connect(audioCtx.destination)

          processor.onaudioprocess = e => {
            socket.emit('Voice', e.inputBuffer.getChannelData(0))
          }

          socket.on('Voice', msg => {
            const source = audioC.createBufferSource();
            source.buffer = msg;
            source.connect(audioC.destination);
            source.start()
          })
          audioCtx.resume()
        },
        err => console.error(err)
      )
    }

服务器端

//Server shit
const path = require('path');
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const { stringify } = require('querystring');
const { compileFunction } = require('vm');
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(express.static(path.join(__dirname, 'public')));
const PORT = 3000 || process.env.PORT;
server.listen(PORT,  console.log('Server is running on port 3000'))

//variables
var clients = [{}]
var rooms = [{}]

io.on('connection', (socket) => {

    socket.on('Voice', (msg) => {
        console.log(msg)
        socket.emit('Voice', msg)
    })

})

此时在代码中..

socket.on('Voice', msg => {
            const source = audioC.createBufferSource();
            source.buffer = msg;
            source.connect(audioC.destination);
            source.start()
          })

当我记录 msg 时,它给了我一个 arrayBuffer,然后我使用上面的过程将 arrayBuffer 转换为 audioBuffer,但它只是给了我相同的错误消息。几天来,我一直在用头撞墙试图解决这个问题,所以如果有人有解决方案,我会非常感激。

【问题讨论】:

    标签: javascript audio socket.io web-audio-api mediastream


    【解决方案1】:

    您发送的数据是 Float32Array 的 channelData。

    socket.emit('Voice', e.inputBuffer.getChannelData(0))
    

    我对 socket.io 不太熟悉,但我认为数据也以Float32Array 的形式到达另一端。在这种情况下,您必须先使用该数据构建一个 AudioBuffer,然后才能将其与 AudioBufferSourceNode 一起使用。

    const audioBuffer = new AudioBuffer({
        length: msg.length,
        sampleRate: sampleRateOfTheAudioContextOfTheSender
    });
    
    audioBuffer.copyToChannel(msg, 0, 0);
    

    audioBuffer 然后可以与AudioBufferSourceNode 一起使用。

    source.buffer = audioBuffer;
    

    【讨论】:

    • 数据作为arrayBuffer到达,当我控制台记录它记录的数据“arrayBuffer(8192)”
    • 我能够创建一个 Float32array 并使用您在此示例中给我的内容并且它有效,但质量很差且不稳定。我看到有人遇到了确切的问题,有人回答说通过改变波特率和降低音质可以解决这个问题,问题是我不知道该怎么做
    • 更新:一切都很好,您的解决方案运行良好,我所要做的就是更改一个 float32Array,然后取出一行用于调试但从未取出的代码。一旦我把它拿出来,零波动,一切都很顺利。非常感谢您的帮助!!!!!!!!!
    • 我很高兴听到这个消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    相关资源
    最近更新 更多