【问题标题】:FFMPEG : Fill/Change (part of) audio waveform color as per actual progress with respect to time progressFFMPEG:根据时间进度的实际进度填充/更改(部分)音频波形颜色
【发布时间】:2026-02-02 08:40:01
【问题描述】:

我正在尝试制作从 mp3 文件生成波形并显示在背景图像上并播放音频的命令。 与此一起,我想根据整个视频时间的流逝从左到右更改波形颜色(类似于进度条)。

我创建了以下命令,该命令使用drawbox显示进度条以根据当前时间位置填充框颜色。

ffmpeg -y -loop 1 -threads 0 -i sample_background.png -i input.mp3 -filter_complex "color=red@0.5:s=1280x100[Color];[0:v]drawbox=0:155:1280 :100:gray@1:t=fill[baserect];[1:a]aformat=channel_layouts=mono,showwaves=s=1280x100:rate=7:mode=cline:scale=sqrt:colors=0xffffff[波形]; [baserect][波形] 叠加=0:155 [v1];[v1][颜色] 叠加=x='if(gte(t,0), -W+(t)*64, NAN)':y=155 :format=yuv444[v2]" -map "[v2]" -map 1:a -c:v libx264 -crf 35 -ss 0 -t 20 -c:a 复制 -shortest -pix_fmt yuv420p -threads 0 output_withwave_and_progresbar.mp4

但我想在生成的音频波形中显示进度,而不是使用 drawbox 制作/填充矩形。

所以我尝试制作 2 个不同颜色的 2 个波形并相互叠加,我想展示这样一种方式,即顶部波形应该只显示从 x 位置(左)到当前时间的一部分。

ffmpeg -y -loop 1 -threads 0 -i sample_background.png -i input.mp3 -filter_complex "[0:v]drawbox=0:155:1280:100:gray@1:t=fill[baserect] ;[1:a]aformat=channel_layouts=mono,showwaves=s=1280x100:rate=7:mode=cline:scale=sqrt:colors=0xff0000[波形];[1:a]aformat=channel_layouts=mono,showwaves= s=1280x100:rate=7:mode=cline:scale=sqrt:colors=0xffffff[waveform2];[baserect][waveform] overlay=0:155 [v1];[v1][waveform2] overlay=x='if (gte(t,0), -W+(t)*64, NAN)':y=155:format=yuv444[v2]" -map "[v2]" -map 1:a -c:v libx264 -crf 35 -ss 0 -t 20 -c:a copy -shortest -pix_fmt yuv420p -threads 0 test.mp4

但我无法找到从左到右进行擦除效果的方法,目前它正在滑动(因为我正在更改覆盖的 x) 可以使用 alpha 合并并将所有其他像素设置为透明并仅显示小于 x pos 的像素来完成。 但我无法找到如何做到这一点。

背景图片:

我们可以使用任何mp3文件文件,目前我设置了20秒的持续时间。

有人可以指导我们如何做到这一点吗?

谢谢。

【问题讨论】:

    标签: ffmpeg


    【解决方案1】:

    使用混合过滤器,即

    ffmpeg -y -loop 1 -threads 0 -i sample_background.png -i input.mp3 -filter_complex "[0:v]drawbox=0:155:1280:100:gray@1:t=fill[baserect];[1:a]aformat=channel_layouts=mono,asplit[red][white];[red]showwaves=s=1280x100:rate=7:mode=cline:scale=sqrt:colors=0xff0000[red];[white]showwaves=s=1280x100:rate=7:mode=cline:scale=sqrt:colors=0xffffff[white];[red][white]blend=all_expr='if(lte(X/W,T/64),A,B)'[waveform];[baserect][waveform]overlay=0:155:format=yuv444[v]" -map "[v]" -map 1:a -c:v libx264 -crf 35 -ss 0 -t 20 -c:a copy -shortest -pix_fmt yuv420p -threads 0 test.mp4

    其中64 是音频的总时长。

    【讨论】:

    • 非常感谢@Gyan 的快速回答。效果很好。
    • 我正在使用此命令在图像上创建声波,一切都很好,除了声波只在视频中间创建。是否可以将声波移动到视频图像的顶部/底部? ffmpeg -i kina_can_we_kiss_forever.mp3 -i 'w.jpg' -filter_complex "[0:a]showwaves=s=1280x720:mode=line:colors=white,format=yuva420p[v];[1:v]scale=1280:720[bg];[bg][v]overlay[outv]" -map "[outv]" -map 0:a -c:v libx264 -c:a copy output.mov
    • 将叠加层更改为overlay=y=X,其中 X 是垂直位置。