如何仅通过管道实现无中间文件的音频流编码工作流(无需mkfifo)
如何仅通过管道实现无中间文件的音频流编码工作流(无需mkfifo)
这问题我太有共鸣了——存储空间吃紧的时候,生成一堆中间WAV文件简直是灾难!直接给你两套纯管道的解决方案,全程不产生任何临时文件,也完全不需要用mkfifo:
方案一:用ffmpeg(推荐,兼容性更强)
ffmpeg对音频格式的处理更灵活,还能直接批量拼接MP3流,效率更高:
ffmpeg -i "concat:$(printf "%s|" *.mp3 | sed 's/|$//')" -f s16le -ac 2 -ar 44100 - | sox -t raw -r 44100 -c 2 -e signed-integer - -t wav - | opusenc --bitrate 64 - output.opus
拆解一下每个环节:
concat:$(printf "%s|" *.mp3 | sed 's/|$//'):用ffmpeg的concat协议把所有MP3文件直接拼接成一个输入流,省掉了逐个解码再拼接的步骤-f s16le -ac 2 -ar 44100 -:指定输出为16位小端有符号整数的PCM流,双声道、44100采样率,输出到标准输出(-代表stdout)sox -t raw -r 44100 -c 2 -e signed-integer - -t wav -:告诉sox输入是raw格式的PCM(参数和ffmpeg输出完全匹配),处理后输出WAV格式到标准输出opusenc --bitrate 64 - output.opus:opusenc读取标准输入的WAV流,编码成64kbps的Opus文件
方案二:用lame(适配你原本的工具链)
如果你更习惯用lame解码,也可以这样写,前提是所有MP3的采样率、声道数一致:
for i in *.mp3; do lame --decode "$i" -; done | sox -t wav - -t wav - | opusenc --bitrate 64 - output.opus
解释一下:
lame --decode "$i" -:把每个MP3解码成完整的WAV流输出到stdout- 循环会把所有WAV流依次管道给sox,sox能自动识别WAV头部并完成拼接
- 后续的sox处理和opusenc编码和方案一逻辑一致
注意事项
- 确保所有输入MP3的音频参数(采样率、声道数、位深)一致,否则拼接或处理时会报错。如果参数不一致,可以在ffmpeg或sox里加参数统一,比如在sox里加
-r 44100 -c 2强制转换 - 用ffmpeg的concat协议时,所有MP3必须是同一种编码格式(这点MP3一般都满足),否则需要先统一格式再拼接
- 如果你的SoX需要加自定义滤镜,直接在sox命令里插入即可,比如
sox -t raw ... -t wav - highpass 100 lowpass 5000
备注:内容来源于stack exchange,提问作者user415275
相关产品推荐
相关产品推荐

