【问题标题】:Is there any way to save mulaw audio stream from twilio in a file有什么方法可以将来自 twilio 的 mulaw 音频流保存在文件中
【发布时间】:2023-03-31 20:30:02
【问题描述】:

我正在使用 Twilio 语音流功能,但我不想使用 Twilio 录制功能。当 Twilio 开始向我的服务器发送语音流时,我想将其作为音频文件实时存储到磁盘中。

【问题讨论】:

    标签: twilio audio-streaming nodejs-stream twilio-programmable-voice


    【解决方案1】:

    我今天遇到了同样的问题,并想出了一种为 mu-law 标头生成 WAVE 标头的方法:

    如果你关注Twilio's blog post,这就是我最终实现的代码:

    wss.on('connection', (socket) => {
      socket.on('message', (msg) => {
        const { event, ...message } = JSON.parse(msg);
        switch (event) {
          case 'start':
            let streamSid = message.start.streamSid;
            socket.wstream = fs.createWriteStream(__dirname + `/${Date.now()}.wav`, { encoding: 'binary' });
            // This is a mu-law header for a WAV-file compatible with twilio format
            socket.wstream.write(Buffer.from([
              0x52,0x49,0x46,0x46,0x62,0xb8,0x00,0x00,0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,
              0x12,0x00,0x00,0x00,0x07,0x00,0x01,0x00,0x40,0x1f,0x00,0x00,0x80,0x3e,0x00,0x00,
              0x02,0x00,0x04,0x00,0x00,0x00,0x66,0x61,0x63,0x74,0x04,0x00,0x00,0x00,0xc5,0x5b,
              0x00,0x00,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x00, // Those last 4 bytes are the data length
            ]));
            break;
          case 'media':
            // decode the base64-encoded data and write to stream
            socket.wstream.write(Buffer.from(message.media.payload, 'base64'));
            break;
          case 'stop':
            // Now the only thing missing is to write the number of data bytes in the header
            socket.wstream.write("", () => {
              let fd = fs.openSync(socket.wstream.path, 'r+'); // `r+` mode is needed in order to write to arbitrary position
              let count = socket.wstream.bytesWritten;
              count -= 58; // The header itself is 58 bytes long and we only want the data byte length
              console.log(count)
              fs.writeSync(
                fd,
                Buffer.from([
                  count % 256,
                  (count >> 8) % 256,
                  (count >> 16) % 256,
                  (count >> 24) % 256,
                ]),
                0,
                4, // Write 4 bytes
                54, // starts writing at byte 54 in the file
              );
            });
            break;
        }
      });
    });
    

    【讨论】:

    • 只有一个问题——你是如何理解和创造这个的????
    • 这是一个很棒的代码 sn-p。效果很好。我已经采用了这个 sn-p 并为这里需要它的任何人制作了一个易于使用的 npm 库包:npmjs.com/package/twilio-media-stream-save-audio-file
    【解决方案2】:

    您可以使用FFmpeg 将 Twilio mulaw 转换为常规 WAV 文件。
    如果您使用下面的类,那么您只需要在 Twilio 流缓冲区到达时发送它们。

    类似:

    recording = StreamAudioRecording(tempDirectory)
    recording.start_recording(call_id)
    
    <loop over buffer packets arriving>
        recording.write_buffer(buffer)
    
    recording_audio_path = recording.stop_recording()
    

    这是类的实现

    import os
    
    RAW_AUDIO_FILE_EXTENSION = "ulaw"
    CONVERTED_AUDIO_FILE_EXTENSION = "wav"
    
    
    class StreamAudioRecording:
        def __init__(self, audio_recording_path):
            self.audio_recording_path = audio_recording_path
            self.f = None
            self.audio_file_path = None
    
        def start_recording(self, call_id):
             self.audio_file_path = os.path.join(self.audio_recording_path, f" . 
                   {call_id}.{RAW_AUDIO_FILE_EXTENSION}")
             self.f = open(self.audio_file_path, 'wb')
    
        def write_buffer(self, buffer):
            self.f.write(buffer)
    
        def stop_recording(self):
            self.f.close()
            converted_audio_path = 
                self.audio_file_path.replace(RAW_AUDIO_FILE_EXTENSION,
                                             CONVERTED_AUDIO_FILE_EXTENSION)
            self.convert_call_recording(self.audio_file_path, converted_audio_path)
    
            return converted_audio_path
    
        @staticmethod
        def convert_call_recording(mulaw_path, wav_path):
            command = f"ffmpeg -y -loglevel panic -f mulaw -ar 8k -ac 1 -i {mulaw_path} {wav_path}"
            os.system(command)
    

    【讨论】:

      【解决方案3】:

      如果您使用 Node.js,@tdeo 提供的解决方案效果很好。我受到启发,并使用此解决方案制作了一个简单的库。它现在可以在 npm 上使用。

      https://www.npmjs.com/package/twilio-media-stream-save-audio-file

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-09
        • 1970-01-01
        • 2021-12-15
        相关资源
        最近更新 更多