使用FFmpeg生成波形图

27

我正在尝试使用 ffmpeg 生成波形图像。

虽然我已经成功生成了一个波形图像,但它看起来不是很好看...

我一直在寻找方法来为图像添加样式,使其看起来更加漂亮,但是我一直无法找到关于这方面的信息或教程。

我正在使用 PHP 和 shell_exec 来创建波形。

我知道有一些PHP库可以做到这一点,但由于文件格式问题,这是一个费时的过程。

我正在使用以下代码:

$command = 'convertvid\bin\ffmpeg -i Temp\\'.$file.' -y -lavfi showwavespic=split_channels=0:s='.$width.'x50 Temp\\'.$PNGFileName;
shell_exec($command);

基本上我想要在中间添加一行,因为目前存在空白区域并希望能够设置背景颜色和波浪颜色。

1个回答

69

默认波形

Default waveform

ffmpeg -i input.wav -filter_complex showwavespic -frames:v 1 output.png

注意事项

  • 请注意音频中间的静默段落(如果您想要添加一条线,请参见下面的“花哨波形”)。

  • 背景是透明的。

  • 默认颜色为红色(左声道)和绿色(右声道),用于立体声输入。颜色在通道重叠处混合。

  • 您可以使用colors选项更改通道颜色,例如"showwavespic=colors=blue|yellow"。查看有效颜色名称列表或使用十六进制表示法,例如#ffcc99

  • 有关其他选项,请参见showwavespic过滤器文档

  • 如果您想要一个视频而不是图像,请使用showwaves过滤器

花哨波形

Fancy waveform

ffmpeg -i input.mp4 -filter_complex \
"[0:a]aformat=channel_layouts=mono, \
 compand=gain=-6, \
 showwavespic=s=600x120:colors=#9cf42f[fg]; \
 color=s=600x120:color=#44582c, \
 drawgrid=width=iw/10:height=ih/5:color=#9cf42f@0.1[bg]; \
 [bg][fg]overlay=format=auto,drawbox=x=(iw-w)/2:y=(ih-h)/2:w=iw:h=1:color=#9cf42f" \
-frames:v 1 output.png

选项说明

  1. aformat 将音频降采样为单声道。否则,默认情况下,立体声输入将导致每个通道的波形颜色不同(请参见上面的默认波形示例)。

  2. compand 修改音频的动态范围,使波形看起来不那么平坦。它会使实际音频的表示不太准确,但对于某些输入可能更具视觉吸引力。

  3. showwavespic 生成实际的波形。

  4. color 源过滤器用于制作与波形大小相同的彩色背景。

  5. drawgrid 在背景上添加网格。网格不代表任何东西,只是为了美观。网格颜色与波形颜色相同(#9cf42f),但不透明度设置为10%(@0.1)。

  6. overlay[bg](我为背景命名的过滤图)放在[fg](波形)后面。

  7. 最后,drawbox 将制作水平线,以便任何静音区域都不会是空白的。

渐变示例

Gradient example

使用渐变过滤器
ffmpeg -i input.mp3 -filter_complex "gradients=s=1920x1080:c0=000000:c1=434343:x0=0:x1=0:y0=0:y1=1080,drawbox=x=(iw-w)/2:y=(ih-h)/2:w=iw:h=1:color=#0000ff[bg];[0:a]aformat=channel_layouts=mono,showwavespic=s=1920x1080:colors=#0068ff[fg];[bg][fg]overlay=format=auto" -vframes:v 1 output.png

颜色背景

waveform with simple color background

ffmpeg -i input.opus -filter_complex "color=c=blue[color];aformat=channel_layouts=mono,showwavespic=s=1280x720:colors=white[wave];[color][wave]scale2ref[bg][fg];[bg][fg]overlay=format=auto" -frames:v 1 output.png

scale2ref滤镜会自动将背景大小调整为与波形相同。

图像背景

当然,您也可以使用图像或视频作为背景:

Image background example

ffmpeg -i audio.flac -i background.jpg -filter_complex \
"[1:v]scale=600:-1,crop=iw:120[bg]; \
 [0:a]showwavespic=s=600x120:colors=cyan|aqua[fg]; \
 [bg][fg]overlay=format=auto" \
-q:v 3 showwavespic_bg.jpg

获取波形统计信息和数据

使用astats过滤器。有许多可用的统计信息:RMS、峰值、最小值、最大值、差异等。

每个音频帧的RMS电平

以下是获取每个音频帧中标准RMS电平(以dBFS为单位)的示例:

ffprobe -v error -f lavfi -i "amovie=input.wav,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of csv=p=0 > rms.log

每秒峰值

添加asetnsamples过滤器。

ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.Peak_level -of csv=p=0

与上述相同,但包含时间戳。
ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.Peak_level -of csv=p=0

输出到文件

只需在命令的末尾添加> output.log即可:

ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of csv=p=0 > output.log

JSON

ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of json > output.json

1
谢谢LongNeckbeard,你是FFmpeg大师!当我执行“boring default wav”命令时,它已经具有透明背景和红色波形,我不必添加额外的东西,这非常好。 - Jeff
1
选项“colors”未找到--我想我需要一个构建标志。 - chovy
1
@chovy,你的ffmpeg版本太旧了。请查看FFmpeg下载页面,获取适用于你的操作系统的“静态构建”链接。 - llogan
假设输入的采样率为44100,请尝试使用ffprobe -v error -f lavfi -i amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1 -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of csv=p=0命令。请参考astats过滤器以选择其他统计数据。 - llogan
1
@Jérémy 请参考答案中的“每个音频帧的RMS电平”命令,但将 -of csv=p=0 > rms.log 改为 -of json > output.json - llogan
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接