I'm trying to create a video using the follwing code:
`$`ffmpeg -loop 1 -r 5 -i video.png -r 5 -i progress.png -filter_complex "overlay=x='if(gte(t,0), -W+(t)*5, NAN)':y=H-h" -i video.mp3 -acodec copy video.mp4
I have the following files
- video.png
- this is a 1280x720 px still frame that is simply a background with a waveform of the video.mp3 file
- progress.png
- this is simply a 1280x100 px semi-transparent image that should simulate an animation (from from 0 to 100% of the width of the video.png file, in order to simulate "fill up" animation.
My issues are as following:
- The video is not in sync with the audio. The progress bar is way off, instead of finishing at the end of the song, it just keeps going on and on and on and on...
- Also... it just keeps going on and on! I left it create a 1 hour video and it never stopped.
I know I'm missing something in the filter, but I have no idea how I could fix it.
Could someone lend me some help?
As Pranav said, use -shortest
at the end of the stream to sort the duration issue.
Now to sync the progress of your frame you've got to figure out how much your overlayed picture needs to move per second. This is simple: you need to move your picture by "Width of your video / Duration of your video"
For instance if you've got a 3 minutes song and a video width of 1280:
- 3 minutes = 3x60 = 180 seconds.
- "Width of your video / Duration of your video" = 1280 / 180 = 7.11 pixels / second.
7.11
is the value to use instead of 5
in -W+(t)*5,
.
I hope this is clear enough.
Sorry for answering so late!
@AJ29: I decided to give up on the whole overlay video deal and you were spot on.
The overlay filter was processing with yuv420, thus moving the image in 2px increments; setting overlay=format=yuv444 made the animation pixel-by-pixel.
ffmpeg -y -i "wanderhouse - Sugar.mp3" -loop 1 -i frame.png -i waveform.png -i progress.png -filter_complex "[1][2]overlay=x=0:y=H-h:eval=init[over];[over]drawtext=fontfile=impact.ttf:fontsize=72:text='WANDERHOUSE- - SUGAR':x=(w-text_w)/2:y=(h-170-text_h):fontcolor=white:shadowy=2:shadowx=2:shadowcolor=black[text];[text][3] overlay=x='floor(if(lt(-W+(n)*0.248182258846,0), -W+(n)*0.248182258846))':y=H-h:format=yuv444" -shortest -acodec copy -vcodec libx264 -pix_fmt yuv420p -preset ultrafast -crf 10 video.mp4 -report
Is what I came up in the end. 0.248182258846
is the amount of pixels I have to move the "progress.png" each frame (n).
Thanks for your tips!
@mark4o: I figured that out, eventually. I tried going the qrtle way of creating a video with an alpha channel then setting it on top of my "other" video", but I failed miserably at syncing them and I gave up.
The end result of my work: https://www.youtube.com/watch?v=H8uHTIXO0p0