使用beep模块播放并保存音频时WAV文件过大的问题求助
问题:beep混音器保存音频生成超大文件的解决方法
我使用beep模块播放音频,希望同时将播放的音频流保存到文件或HTTP端点。目前通过以下方式向混音器添加流:
soundMixer.Add(stream) speaker.Play(s.soundMixer)
需要修改的代码位于项目src/sound.go的222-225行。
尝试用wav.Encode保存混合音频时,生成的文件体积超大(甚至达到50G),推测是音频流播放完毕后,混音器持续输出静音导致的。
核心原因
beep.Mixer的默认行为是持续输出静音,即使所有添加的音频流都已播放完毕,它也不会主动停止,这就导致编码器一直写入静音数据,最终生成超大文件。
解决方法
方法1:自定义自动停止的混音器包装流
创建一个包装器,监听混音器内的活跃流数量,当没有活跃流时主动停止输出,让编码器终止写入。
步骤1:定义包装流结构
type AutoStopMixer struct { mixer *beep.Mixer } // Stream 重写Stream方法,无活跃流时停止输出 func (asm *AutoStopMixer) Stream(samples [][2]float64) (n int, ok bool) { if len(asm.mixer.Streams) == 0 { return 0, false // 无活跃流,返回false终止编码 } return asm.mixer.Stream(samples) } // Err 传递混音器的错误信息 func (asm *AutoStopMixer) Err() error { return asm.mixer.Err() }
步骤2:替换原混音器使用
在你项目的src/sound.go对应位置修改:
// 原添加流逻辑 soundMixer.Add(stream) // 创建自动停止的混音器包装器 autoStopMixer := &AutoStopMixer{mixer: soundMixer} // 异步播放(避免编码阻塞播放) go func() { speaker.Play(autoStopMixer) }() // 保存音频到文件 outFile, err := os.Create("mixed_audio.wav") if err != nil { log.Fatal(err) } defer outFile.Close() // 使用输入流的原生格式,不要硬编码 inputFormat := stream.Format() err = wav.Encode(outFile, autoStopMixer, inputFormat) if err != nil { log.Fatal(err) }
方法2:限制编码时长(已知音频总时长时使用)
如果提前知道音频的总时长,可以用beep/effects的Take函数截取指定时长的流,避免无限输出静音:
import "github.com/faiface/beep/effects" import "time" // 假设音频总时长为15秒,转换为样本数 totalSamples := stream.Format().SampleRate.D(15 * time.Second) limitedStream := effects.Take(totalSamples, soundMixer) // 使用截取后的流编码 err = wav.Encode(outFile, limitedStream, stream.Format())
内容的提问来源于stack exchange,提问作者Dhairya Verma
相关产品推荐
相关产品推荐

