【问题标题】:Save a Twilio <Stream> of format 8Khz `mulaw` to a file将格式为 8Khz `mulaw` 的 Twilio <Stream> 保存到文件中
【发布时间】:2020-03-31 16:58:10
【问题描述】:

有几个帖子解决了这个问题,但我无法成功播放保存的文件。它通常以半速播放。

Convert 8kHz mulaw to 16KHz PCM in real time

使用上述问题中接受的答案,我将原始和base64解码的音频保存在go中:

// Media event
type Media struct {
    Track     string `json:"track"`
    Chunk     string `json:"chunk"`
    Timestamp string `json:"timestamp"`
    Payload   string `json:"payload"`
}

// SaveAudio will upgrade connection to websocket and save the audio to file
func SaveAudio(w http.ResponseWriter, r *http.Request) {
    utility.DebugLogf("SaveAudio")
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Print("upgrade:", err)
        return
    }

    defer utility.SafeClose(c)
    inBuf := bytes.Buffer{}

    loop := true
    for loop == true {
        _, message, err := c.ReadMessage()
        utility.PanicIfErr(err)
        decMessage := TwilioWSSMessage{}
        err = json.Unmarshal(message, &decMessage)
        utility.PanicIfErr(err)

        switch decMessage.Event {
        case "connected":
            utility.DebugLogf("Connected a %s protocol version:%s", decMessage.Protocol, decMessage.Version)
        case "start":
            utility.DebugLogf("Starting audio stream: %#v", decMessage.Start)
        case "media":
            chunk, err := base64.StdEncoding.DecodeString(decMessage.Media.Payload)
            utility.PanicIfErr(err)
            _, err = inBuf.Write(chunk)
            utility.PanicIfErr(err)
        case "stop":
            utility.DebugLogf("Ending audio stream: %#v", decMessage.Stop)
            loop = false
        default:
            utility.LogWarningf("Unrecognized event type: %s", decMessage.Event)
            loop = false
        }
    }

    saveRaw(&inBuf)
}

func saveRaw(buf *bytes.Buffer) {
    rawOut, err := os.Create("out.ulaw")
    utility.PanicIfErr(err)

    _, err = rawOut.Write(buf.Bytes())
    utility.PanicIfErr(err)
}

然后我用ffmpegmulaw转换成默认的pcm_s16le

ffmpeg -f mulaw -ar 8000 -ac 1 -i out.ulaw mulaw_decoded.wav 

然后将音频从 8k->16k 上采样并用 vlc 播放:

ffmpeg -i mulaw_decoded.wav -ar 16000 upsampled.wav && vlc upsampled.wav

但它以半速播放。

最终我想在 rust 或 go 中完成这一切,但我什至无法仅使用 ffmpeg 在本地工作。

提前致谢。


上述两个ffmpeg 操作结合建议的 sox 重采样器的输出:

命令:

ffmpeg -y -loglevel verbose -f mulaw -ar 8000 -ac 1 -bits_per_raw_sample 8 -i testsamples/raw_mulaw_bytes -af aresample=resampler=soxr -ar 16000 upsampled.wav

输出:

[mulaw @ 0x7fecc0814000] Estimating duration from bitrate, this may be inaccurate
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, mulaw, from 'testsamples/raw_mulaw_bytes':
  Duration: 00:00:20.74, bitrate: 64 kb/s
    Stream #0:0: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_mulaw (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
[graph_0_in_0_0 @ 0x7fecc0505600] tb:1/8000 samplefmt:s16 samplerate:8000 chlayout:0x4
[Parsed_aresample_0 @ 0x7fecc0505280] ch:1 chl:mono fmt:s16 r:8000Hz -> ch:1 chl:mono fmt:s16 r:16000Hz
Output #0, wav, to 'upsampled.wav':
  Metadata:
    ISFT            : Lavf58.29.100
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, mono, s16, 256 kb/s
    Metadata:
      encoder         : Lavc58.54.100 pcm_s16le
No more output streams to write to, finishing.
size=     648kB time=00:00:20.74 bitrate= 256.0kbits/s speed=1.55e+03x
video:0kB audio:648kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.011753%
Input file #0 (testsamples/raw_mulaw_bytes):
  Input stream #0:0 (audio): 519 packets read (165920 bytes); 519 frames decoded (165920 samples);
  Total: 519 packets (165920 bytes) demuxed
Output file #0 (upsampled.wav):
  Output stream #0:0 (audio): 200 frames encoded (331840 samples); 200 packets muxed (663680 bytes);
  Total: 200 packets (663680 bytes) muxed
[AVIOContext @ 0x7fecc0433cc0] Statistics: 4 seeks, 6 writeouts
[AVIOContext @ 0x7fecc042a6c0] Statistics: 165920 bytes read, 0 seeks

音频听起来和以前一样

【问题讨论】:

  • this answer 是否提供了解决方案(尤其是看到它的最后一条评论)?
  • 附带说明,请不要以您的方式提问:所述问题与 Go 和/或 websockets 和/或 µ-law 编解码器无关:它纯粹是关于特定的尝试使用ffmpeg 对音频文件进行上采样时出现问题,所以这样问它并像这样标记它。如果/当您在使用 Go 作为编程语言来实现某些东西时遇到问题,请发布一个带有 go 标记的单独问题。这个特定的问题不包含编程问题。
  • 好的,感谢您的编辑,不,那个答案没有解决它。与以下结果相同:ffmpeg -y -i mulaw_decoded.wav -af aresample=resampler=soxr -ar 16000 upsampled.wav &amp;&amp; vlc upsampled.wav - 我将 ffmpeg 输出添加到问题中

标签: ffmpeg twilio resampling


【解决方案1】:

感谢这个答案,我终于弄明白了:Slow motion effect when decoding OPUS audio stream

他提到的地方:

“慢动作”的另一个可能原因是同一解码器解码了多个流。但在这种情况下,您也会得到失真的慢速音频。

所以这次通话的轨道是inboundoutbound 所以在case "media": 只保存一首曲目:

if decMessage.Media.Track == "outbound" {
  chunk, err := base64.StdEncoding.DecodeString(decMessage.Media.Payload)
  utility.PanicIfErr(err)
  _, err = outboundBuf.Write(chunk)
  utility.PanicIfErr(err)
}

ffmpeg 命令按预期工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 2023-03-31
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    相关资源
    最近更新 更多