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

我有一个 Go 应用程序,我想在其中将未压缩的实时音频流式传输到浏览器。我希望通过让浏览器打开与流相对应的 URL,然后将音频数据提供给该连接来通过 HTTP 进行流传输。

我打算使用 WAV 发送未压缩的数据,但是 WAV 文件格式要求在标头中预定义文件大小。是否有更好的容器格式可以在 Go 中轻松使用此流媒体?

我知道一种方法是使用适当的流媒体服务器并通过它对我的音频进行转码,但如果我自己实现这一点,是否有一种相当简单的方法可以开始?也许是一个让这更容易的 Go 库?


互换的青春
浏览 275回答 2
2回答

扬帆大鱼

如果您仍在考虑未压缩的 WAV 以获得最终质量,那么我认为您有两种选择躺在标题中 - 说 WAV 很长(说 2GB)将额外的块添加到 RIFF 容器中第一种选择很容易实现,但意味着幼稚的浏览器会尝试下载 2GB 的文件而不是流式传输它。我希望任何实现 HTML5 的东西都不会那么天真,但我认为您需要尝试一下。RIFF 规范似乎支持第二个选择,即添加额外的块,其中WAV 文件是其子集。然后,您可以编写一个 WAV 文件,其中包含多个较短的声音数据块。这应该被 WAV 播放器支持,但可能不是因为 WAV 文件从来没有特别好的标准化,而且很多播放器只是寻找一个 44 字节的标头,它不是很符合 RIFF 标准!如果我是你,我会先尝试第一个选项,看看效果如何。

繁星coding

好的,这就是我最终要做的,我的 Go 代码通过 ffmpeg 过程将原始 PCM 数据通过管道传输,该过程将其转换为 mp3。我假设packets是我的音频数据出现的通道,并且response是一个 http.ResponseWritercmd := exec.Command("ffmpeg", "-v", "verbose", "-f", "u16le", "-ar", "44100", "-ac", "1", "-i", "-", "-f", "mp3", "-")audioIn, err := cmd.StdinPipe()if err != nil {&nbsp; &nbsp; log.Println("Failed to create stdin pipe")}audioOut, err := cmd.StdoutPipe()if err != nil {&nbsp; &nbsp; log.Println("Failed to create stdout pipe")}err = cmd.Start()if err != nil {&nbsp; &nbsp; log.Println("Failed to start ffmpeg command, error: ", err)}go func() {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; packet := <-packets&nbsp; &nbsp; &nbsp; &nbsp; audioIn.Write(packet.Payload)&nbsp; &nbsp; }}go func() {&nbsp; &nbsp; amount, err := io.Copy(response, audioOut)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Println("io copy terminated with an error", err)&nbsp; &nbsp; }&nbsp; &nbsp; log.Printf("Done copying audio data: %d bytes\n", amount)}()err = cmd.Wait()if err != nil {&nbsp; &nbsp; log.Println("ffmpeg command terminated incorrectly", err)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go