FFMPEG : Fill/Change (part of) audio waveform colo

2019-07-23 01:22发布

问题:

I am trying to make command which is generating waveform from mp3 file and show on background image and play audio. Togethr with this, I want to change waveform color left to right (something like progressbar) as per overall video time elapses.

I have created following command which shows progress bar using drawbox to fill box color as per current time position.

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[waveform]; [baserect][waveform] overlay=0:155 [v1];[v1][Color] 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 output_withwave_and_progresbar.mp4

But I want to show progress inside generated audio waveform instead of making / filling rectangle using drawbox.

So I have tried to make 2 waveform of 2 different color and overlay on each other and I wanted to show such a way that top waveform should display only part from x position (left) respective to current time.

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[waveform];[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

But I am not able to find way to do Wipe effect from left to right, currently it is sliding (as I am changing x of overlay) It might be done using alpha merge and setting all other pixel to transparent and only show pixels which are less than x pos. but I am not able to find how to do this.

Background image:

we can use any mp3 file file, currently I have set 20 sec duration.

Can someone please guide how we can do this?

Thanks.

回答1:

Use the blend filter i.e.

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

where 64 is total duration of audio.



标签: ffmpeg