首页 > 解决方案 > 如何连接流式音频?

问题描述

我有一个网络应用程序,可以记录来自用户麦克风的音频。它将数据发送到服务器。相关代码如下所示:

class Recorder {
  // ...
  setRecorder() {
    this.recorder = new RecordRTC(this.stream, {
      type: 'audio',
      mimeType: this.mimeType,
      recorderType: StereoAudioRecorder,
      timeSlice: 2000, // Interval to send recorded data
      ondataavailable: async blob => { // send the data to the server
        let seq = this.seq++
        let data = await blob.arrayBuffer()
        if(this.socket.connected) {
          try {
            this.socket.emit('audio', {
              id: this.id,
              seq,
              mimeType: this.mimeType,
              data
            })
          } catch (e) {
            console.error('caught an error', e)
            this.stopRecording()
          }
        }
      },
      sampleRate: 44100,
      desiredSampleRate: 44100,
      numberOfAudioChannels: 1
    })
  }
}

在服务器端(Express.js),我将收到的数据发送给任何感兴趣的客户端。以下是相关代码:

app.get('/play', (req, res, next) => {
    try {
      let id = req.query.id
      let mimeType
      if(!recordings[id]) {
        // ...
      }
      emitter // the EventEmitter that's handling this
        .on(`audio ${id}`, data => {
          if(!mimeType) {
            mimeType = data.mimeType
            res.writeHead(200, {'Content-Type': mimeType})
          }
          res.write(data.data)
        })
        .on(`close ${id}`, () => {
          console.debug({type:'audio close', id})
          res.end()
        })
    } catch (e) {
      next(e)
    }
  })

问题是我从客户端获得的每个块似乎都是一个完整的 WAV 文件,并且连接这些文件不起作用。尝试播放此类文件时,您只会听到第一个块。

我一直在寻找有关如何连接输入文件(或任何其他会导致可以收听的流的方法)的信息。似乎关于这个主题的信息很少。

我一直在特别关注ffmpeg,但尽管它声称具有连接文件的能力,但它希望所有文件都在命令行上给出。我正在接收流数据,因此实际上无法提前列出文件名;我必须在 on 中发送多个文件stdin,但这不起作用。

谁能指出我正确的方向?我认为连接音频文件将是一种常见的需求,但如果事先不知道要处理的所有数据,我找不到任何能够做到这一点的工具。还是我在这里吠错了树?

标签: javascriptnode.jsaudiowebrtcstreaming

解决方案


推荐阅读