如何从 UDP 流中实时获取 Overall.RMS_level 作为附加到共享日志文件的整数?

如何从 UDP 流中实时获取 Overall.RMS_level 作为附加到共享日志文件的整数?

我的目标是实时监控 UDP 流的音频,以检测音频是否丢失或音量过低。最终附加到包含分贝整数值的日志文件中。如果只有输出文件规范共享文件例如:

key=lavfi.astats.Overall.RMS_level:sharedfile=log.txt

如果 ffmpeg 以共享写入或共享追加的方式打开文件,则外部脚本将可以访问正在写入的输出文件。

我尝试了 ffprobe 和 ffmpeg,我能得到的唯一有效输出是使用 ffmpeg。

ffmpeg 给出了正确的结果,但是 ffmpeg 会打开指定为“log.txt”的输出文件进行输出锁定,并且不会向其中写入任何数据,直到您按下 ctrl-c 来停止该过程,此时输出文件会关闭。我将编写一个脚本来实时轮询输出文件,因为文件正在被写入,但前提是我能弄清楚如何告诉 ffmpeg 将每个样本附加到“log.txt”中。

请就替代方法或此方法的修复提供建议。

尝试 1 使用 ffmpeg

ffmpeg -i 'udp://@232.1.1.5:30120' -af astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.RMS_level:file=log.txt -f null -

ctrl-c 之后显示“log.txt”内容的文件示例

frame:0    pts:0       pts_time:0
lavfi.astats.Overall.RMS_level=-34.210103
frame:1    pts:1536    pts_time:0.032
lavfi.astats.Overall.RMS_level=-31.515254
frame:2    pts:3072    pts_time:0.064
lavfi.astats.Overall.RMS_level=-32.894668
frame:3    pts:4609    pts_time:0.0960208
lavfi.astats.Overall.RMS_level=-33.187652

尝试 2 使用 ffprobe

ffprobe -i 'udp://@232.1.1.5:30120',astats=metadata=1:reset=1 -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.RMS_level,lavfi.astats.1.RMS_level,lavfi.astats.2.RMS_level -of csv=p=0

这有效并且仅显示时间代码。它在控制台输出中显示 lavfi.astats.Overall.RMS 的空白行。我认为问题与 lavfi 有关?

控制台的示例输出:

22508.110500
22507.361267


22508.143867
22507.393267


22508.177244
22507.425267

我尝试更改命令行以在 -i 输入之前指定 -f lavfi,但它返回错误:

ffprobe -f lavfi  -i 'udp://@232.1.1.5:30120',astats=metadata=1:reset=1 -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.RMS_level,lavfi.astats.1.RMS_level,lavfi.astats.2.RMS_level -of csv=p=0

返回:

[lavfi @ 0x55c69784f840] No such filter: 'udp://'
udp://@232.1.1.5:30120,astats=metadata=1:reset=1: Invalid argument

答案1

我在 1 月 10 日添加了一个选项,允许元数据过滤器立即将数据刷新到磁盘。因此,在更新到 a 后,使用下面修改后的尝试 1当前的git 构建

ffmpeg -i 'udp://@232.1.1.5:30120' -af astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.RMS_level:file=log.txt:direct=1 -f null -

以前,当缓冲区至少有 256kb 时,ffmpeg 会将数据刷新到文件协议输出。这是因为 ffmpeg 处理的正常输出流量是相对庞大的媒体负载,而不是几十个字节的文本。

答案2

我终于找到了一个可行的示例 bash 脚本。

#!/bin/bash
# Run ffmpeg in the background
ffmpeg -nostats -i 'udp://@232.1.1.5:30120' -filter_complex ebur128=peak=true -f null -  >>audio_metadata.txt 2>&1 &
while true; do
  # Output to Screen
  cat audio_metadata.txt | tail -1 | tr -s ' ' | grep -oP '(?<=FTPK: )-?[0-9]+'
  # Output to File
  #cat audio_metadata.txt | tail -1 | tr -s ' ' | grep -oP '(?<=FTPK: )-?[0-9]+' > db_meter.txt
  sleep .3 # Adjust 100ms up or down for best sample rate without too many repeats
done

相关内容