FFmpeg:流式传输音频播放列表,规范响度并生成频谱图和波形



我想使用 FFmpeg 流式传输包含多个音频文件(主要是 FLAC 和 MP3(的播放列表。在播放过程中,我希望 FFmpeg 对音频信号的响度进行归一化,并分别生成音频信号的频谱图和波形。频谱图和波形应用作音频流监视器。最终的音频流、频谱图和波形输出将被发送到浏览器,浏览器播放音频流并连续渲染频谱图和波形"图像"。我还希望能够在播放过程中从播放列表中删除和添加音频文件。

作为第一步,我想使用ffmpeg命令来实现所需的结果,然后再尝试编写以编程方式执行相同操作的代码。

(旁注:我发现了libgroove它基本上可以做我想做的事,但我想了解 FFmpeg 的内部结构并编写我自己的软件。目标语言是 Go,使用goavgo-libav库可能会完成这项工作。但是,我最终可能会用 C 编写代码,然后从 C 创建 Go 语言绑定,而不是依赖其中一个命名库。

这里有一个小概述:

playlist (input) --> loudnorm --> split --> spectrogram --> separate output
|
split ---> waveform ----> separate output
|
+------> encode ------> audio stream output

对于响度归一化,我打算使用loudnorm滤波器,它实现了EBU R128算法。

对于频谱图,我打算使用showspectrumshowspectrumpic滤波器。由于我希望频谱图是"可蒸的",所以我真的不确定如何做到这一点。也许有一种方法可以逐步输出片段?或者也许有一种方法可以逐步输出某种表示(JSON 或任何其他格式(?

对于波形,我打算使用showwavesshowwavespic滤波器。与频谱图相同,因为输出应该是"可流式传输的"。

使用ffmpeg命令实现我想要的东西时遇到了一点麻烦。这是我到目前为止所拥有的:

ffmpeg 
-re -i input.flac 
-filter_complex "
[0:a] loudnorm [ln]; 
[ln] asplit [a][b]; 
[a] showspectrumpic=size=640x518:mode=combined [ss]; 
[b] showwavespic=size=1280x202 [sw]
" 
-map '[ln]' -map '[ss]' -map '[sw]' 
-f tee 
-acodec libmp3lame -ab 128k -ac 2 -ar 44100 
"
[aselect='ln'] rtp://127.0.0.1:1234 | 
[aselect='ss'] ss.png | 
[aselect='sw'] sw.png
"

目前,我收到以下错误:

Output with label 'ln' does not exist in any defined filter graph, or was already used elsewhere.

另外,我不确定aselect是否是要使用的正确功能。有什么提示吗?

你很接近。我认为aselect不正确;它选择要发送到输出的,而不是流。试试这个:

ffmpeg 
-re -i input.flac 
-filter_complex "
[0:a] loudnorm , asplit=3 [a][b][ln];
[a] showspectrumpic=size=640x518:mode=combined [ss];
[b] showwavespic=size=1280x202 [sw]
" 
-map '[ln]' -acodec libmp3lame -ab 128k -ac 2 -ar 44100 -f rtp 'rtp://127.0.0.1:1234' 
-map '[ss]' ss.png 
-map '[sw]' sw.png

请注意,loudnormasplit筛选器组合到一个筛选器链中。从文档中:

筛选器

链由一系列连接的筛选器组成,每个筛选器都连接到序列中的前一个筛选器。筛选器链由","分隔的筛选器说明列表表示。筛选器图由一系列筛选器链组成。过滤器链序列由";"-分隔的过滤器链描述。 [1]

每个-map选项选择一个流并将其发送到下一个输出文件或流。因此,在这种情况下,[ln]流被发送到rtp流,[ss]被发送到ss.png,依此类推。

最新更新