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