【问题标题】:How to create a live media stream with Javascript如何使用 Javascript 创建实时媒体流
【发布时间】:2018-05-31 23:13:33
【问题描述】:

我想创建一个从一台设备到节点服务器的实时音频流,然后该节点服务器可以将该实时源广播到多个前端。

我已经对此进行了广泛的搜索,并且真的碰壁了,所以希望有人可以提供帮助。

我能够从window.navigator.getUserMedia API 获取我的音频输入。

getAudioInput(){
  const constraints = { 
    video: false, 
    audio: {deviceId: this.state.deviceId ? {exact: this.state.deviceId} : undefined},
  };

  window.navigator.getUserMedia(
    constraints, 
    this.initializeRecorder, 
    this.handleError
  );
}

然后将流传递给initializeRecorder 函数,该函数利用AudioContext API 创建一个createMediaStreamSource`

initializeRecorder = (stream) => {
  const audioContext = window.AudioContext;
  const context = new audioContext();
  const audioInput = context.createMediaStreamSource(stream);
  const bufferSize = 2048;
  // create a javascript node
  const recorder = context.createScriptProcessor(bufferSize, 1, 1);
  // specify the processing function
  recorder.onaudioprocess = this.recorderProcess;
  // connect stream to our recorder
  audioInput.connect(recorder);
  // connect our recorder to the previous destination
  recorder.connect(context.destination);
}

在我的recorderProcess 函数中,我现在有一个可以流式传输的AudioProcessingEvent 对象。

目前,我通过套接字连接将音频事件作为流发送,如下所示:

recorderProcess = (e) => {
  const left = e.inputBuffer.getChannelData(0);
  this.socket.emit('stream', this.convertFloat32ToInt16(left))
}

这是最好的还是唯一的方法?有没有更好的方法通过使用fs.createReadStream 然后通过 Axios 发布端点?据我所知,这仅适用于文件而不是连续直播?

服务器

我有一个在 express 上运行的非常简单的套接字服务器。目前我监听流事件,然后发出相同的输入:

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

  client.on('stream', (stream) => {
    client.emit('stream', stream)
  });

});

不确定它的可扩展性如何,但如果您有更好的建议,我很乐意接受。

客户

现在这是我真正陷入困境的地方:

在我的客户端上,我正在监听stream 事件,并希望在我的浏览器中将流作为音频输出收听。我有一个接收事件的函数,但我不知道如何使用返回的 arrayBuffer 对象。

retrieveAudioStream = () => {
  this.socket.on('stream', (buffer) => {
     // ... how can I listen to the buffer as audio
  })
}
  1. 流式传输音频的方式是我可以上传到节点服务器的最佳/唯一方式吗?
  2. 如何侦听客户端返回的 arrayBuffer 对象?

【问题讨论】:

    标签: javascript node.js web-audio-api


    【解决方案1】:
    1. 我流式传输音频的方式是我可以上传到节点服务器的最佳/唯一方式吗?

    不是最好的,但我见过更糟糕的,它不是使用 websockets 的唯一方法,从角度来看它被认为是可以的,因为你希望事情是“实时的”,而不是每 5 秒发送一次 http post 请求。

    1. 如何侦听客户端返回的 arrayBuffer 对象?

    你可以试试这个BaseAudioContext.decodeAudioData来监听数据流,例子很简单。


    从你提供的代码 sn-ps 我假设你想从头开始构建一些东西来了解事情是如何工作的。

    在这种情况下,您可以尝试 MediaStream Recording API 以及将块发送到 X 客户端的 websocket 服务器,以便它们可以重现音频等。

    花时间在WebRTC API 上学习如何从客户端流式传输到另一个客户端是有意义的。

    还可以查看下面的链接以获取一些有用的信息。

    【讨论】:

    • 您是说 WebRTC 会是更好的选择吗?我已经避免使用 WebRTC,因为我理解客户端流必须上传到每个连接的用户,这会导致上传者的带宽问题。我们还想通过一个服务器,这样我们就可以跟踪所有的上传者。我不一定想从头开始构建一些东西。我很高兴使用现有的库,但我一直在努力找到适合我需要的任何东西。你有什么建议吗?
    • 听起来BaseAudioContext.decodeAudioData 是我需要能够回听传入的音频流。我已经尝试过多次使用我传入的 arrayBuffer 块流来实现它,但在需要 audioBuffer 时不断出现错误。您知道如何让BaseAudioContext.decodeAudioData 与我的设置一起使用,还是我需要更改我上传音频流的方式?
    • MDN mdn.github.io/webaudio-examples/decode-audio-data 给出的示例非常简单,关于如何收听,录制需要 Media Recorder API,但由于处于实验状态,您可以使用像 MediaStreamRecorder github.com/streamproc/MediaStreamRecorder 这样的库,您可以捕获音频并将缓冲区流式传输到服务器,然后服务器仅将缓冲区发送给客户端。
    猜你喜欢
    • 2014-09-24
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多