为了账号安全,请及时绑定邮箱和手机立即绑定

HTML5 <audio> 标签的流媒体容器

HTML5 <audio> 标签的流媒体容器

Go
互换的青春 2021-06-05 08:17:58
我有一个 Go 应用程序,我想在其中将未压缩的实时音频流式传输到浏览器。我希望通过让浏览器打开与流相对应的 URL,然后将音频数据提供给该连接来通过 HTTP 进行流传输。我打算使用 WAV 发送未压缩的数据,但是 WAV 文件格式要求在标头中预定义文件大小。是否有更好的容器格式可以在 Go 中轻松使用此流媒体?我知道一种方法是使用适当的流媒体服务器并通过它对我的音频进行转码,但如果我自己实现这一点,是否有一种相当简单的方法可以开始?也许是一个让这更容易的 Go 库?
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

如果您仍在考虑未压缩的 WAV 以获得最终质量,那么我认为您有两种选择

  1. 躺在标题中 - 说 WAV 很长(说 2GB)

  2. 将额外的块添加到 RIFF 容器中

第一种选择很容易实现,但意味着幼稚的浏览器会尝试下载 2GB 的文件而不是流式传输它。我希望任何实现 HTML5 的东西都不会那么天真,但我认为您需要尝试一下。

RIFF 规范似乎支持第二个选择,即添加额外的块,其中WAV 文件是其子集。然后,您可以编写一个 WAV 文件,其中包含多个较短的声音数据块。这应该被 WAV 播放器支持,但可能不是因为 WAV 文件从来没有特别好的标准化,而且很多播放器只是寻找一个 44 字节的标头,它不是很符合 RIFF 标准!

如果我是你,我会先尝试第一个选项,看看效果如何。


查看完整回答
反对 回复 2021-06-07
?
繁星coding

TA贡献1797条经验 获得超4个赞

好的,这就是我最终要做的,我的 Go 代码通过 ffmpeg 过程将原始 PCM 数据通过管道传输,该过程将其转换为 mp3。我假设packets是我的音频数据出现的通道,并且response是一个 http.ResponseWriter


cmd := exec.Command("ffmpeg", "-v", "verbose", "-f", "u16le", "-ar", "44100", "-ac", "1", "-i", "-", "-f", "mp3", "-")

audioIn, err := cmd.StdinPipe()

if err != nil {

    log.Println("Failed to create stdin pipe")

}

audioOut, err := cmd.StdoutPipe()

if err != nil {

    log.Println("Failed to create stdout pipe")

}

err = cmd.Start()

if err != nil {

    log.Println("Failed to start ffmpeg command, error: ", err)

}

go func() {

    for {

        packet := <-packets

        audioIn.Write(packet.Payload)

    }

}

go func() {

    amount, err := io.Copy(response, audioOut)

    if err != nil {

        log.Println("io copy terminated with an error", err)

    }

    log.Printf("Done copying audio data: %d bytes\n", amount)

}()

err = cmd.Wait()

if err != nil {

    log.Println("ffmpeg command terminated incorrectly", err)

}


查看完整回答
反对 回复 2021-06-07
  • 2 回答
  • 0 关注
  • 272 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信