FFMPEG - How to resize an image overlay? - ffmpeg

I need to resize input 3 (logo.gif) to 360x360, but using scale=360:360 just made my video quality really bad. Here's my code:
ffmpeg -y -hide_banner -safe 0 -f concat -i "concat.txt" -i "overlay.png" -i "audio.mp3" -ignore_loop 0 -i "logo.gif" -filter_complex "[0]scale=3840x2160,zoompan=z='if(lte(zoom,1.0),1.25,max(1.001,zoom-0.0012))':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':fps=20:d=200:s=1920x1080[p];[p][1]overlay, scale=1920:1080, drawtext=fontfile=Heathergreen.otf:text=TITLE':fontcolor=black:fontsize=62:x=135:y=940, drawtext=fontfile=voxbox.ttf:text='TEXT':fontcolor=white:fontsize=70:x=120:y=885[v];[2:a]showwaves=mode=cline:s=178x56:r=20:scale=sqrt:colors=0x222222,colorkey=0x000000:0.01:0.1,format=yuva420p[w];[v][3]overlay=20:500[z];[z][w]overlay=108:740[outv]" -map "[outv]" -map 2:a -pix_fmt yuv420p -c:v libx264 -c:a aac -preset veryfast -shortest -movflags faststart -fflags genpts -r 20 "output.mp4"
UPDATE: I've simply resized the image and used that as input rather than resizing during the encode. It works fine, but if anyone has an answer to this I'd be curious to know where I was going wrong.

Instead of [v][3]overlay=20:500[z] you would use [3]scale=360:360[3v];[v][3v]overlay=20:500[z]. Your GIF should be square-shaped to begin with, to avoid distorting it.

Related

Multiple sounds + watermark overlay not working with ffmpeg

I have a problem with an ffmpeg command.
I want to add the same sound several times in the final video and then add a watermark above.
When I do the full command, it doesn't work correctly because the sound is only played once (the first reference):
ffmpeg -i "assets/frame%05d.png" -i "assets/sound.mp3" -loop 1 -i
"assets/watermark.png" -filter_complex
"[1:a]adelay=1000|1000[s1];[1:a]adelay=3000|3000[s2];[s1][s2]amix=2[a];[0:v][2:v]overlay=shortest=1[outv]"
-map "[outv]" -map "[a]" -c:v libx264 -pix_fmt yuv420p -preset ultrafast -y "result.mp4"
When I don't add the watermark, it works correctly:
ffmpeg -i "assets/frame%05d.png" -i "assets/sound.mp3" -filter_complex
"[1:a]adelay=1000|1000[s1];[1:a]adelay=3000|3000[s2];[s1][s2]amix=2[a]"
-map 0:v -map "[a]" -c:v libx264 -pix_fmt yuv420p -preset ultrafast -y "result.mp4"
Try this:
ffmpeg -i "assets/frame%05d.png" \
-stream_loop -1 -i "assets/sound.mp3" \
-loop 1 -i "assets/watermark.png" \
-filter_complex "[1:a]adelay=1000|1000[s1];\
[1:a]adelay=3000|3000[s2];\
[s1][s2]amix=2[a];\
[0:v][2:v]overlay=shortest=1[outv]" \
-map "[outv]" -map "[a]" -shortest \
-c:v libx264 -pix_fmt yuv420p -preset ultrafast -y "result.mp4"
-stream_loop -1 input option loops the input infinitely and -shortest output option stops the audio when video is done.
p.s., I think an aecho filter can combine the 2nd adelay and amix filters.
I found the problem was that the different frames that make up the video were not all correctly encoded which caused the problem with the sounds.
ffmpeg can't read indexed PNG correctly.
You must therefore use this option (for those like me who use imagick):
$imagick->setOption('png:color-type', 6);
$imagick->writeImage('frame00000.png');

Can I combine these 2 commands? (or am I fighting a losing battle?)

I'm very new to ffmpeg but so far I'm enjoying it. But I'm stuck on something. I want to combine these two commands into one, something I'm sure must be possible, but after countless hours and no luck, here I am :)
ffmpeg -y -f concat -safe 0 -protocol_whitelist "file,http,https,tcp,tls" -i "tmp.images.txt" -i "tmp.audio.mp3" -filter_complex "drawbox=y=ih-38:color=black#0.6:width=iw:height=38:t=fill, drawtext=fontfile=Assets/calibrib.ttf:text='%%~ni':fontcolor=white:fontsize=14:x=(w-tw)/2:y=(h)-24" -c:v libx264 -preset veryfast -tune stillimage -shortest -pix_fmt yuv420p "tmp.slide.mp4"
ffmpeg -loop 1 -framerate 2 -i "Assets/studio.jpg" -i tmp.slide.mp4 -filter_complex "[1]scale=879:496[inner];[0][inner]overlay=207:49:shortest=1[out]" -map "[out]" -map 1:a -c:a aac -y tmp.output.mp4
the first line creates a slideshow and places text at bottom
the second line takes the slideshow video and inserts it into a background image before outputting final video
Use
ffmpeg -y -f concat -safe 0 -protocol_whitelist "file,http,https,tcp,tls" -i "tmp.images.txt" -i "tmp.audio.mp3" -i "Assets/studio.jpg" -filter_complex "[0]drawbox=y=ih-38:color=black#0.6:width=iw:height=38:t=fill, drawtext=fontfile=Assets/calibrib.ttf:text='%%~ni':fontcolor=white:fontsize=14:x=(w-tw)/2:y=(h)-24,scale=879:496[inner];[2][inner]overlay=207:49" -c:v libx264 -preset veryfast -tune stillimage -c:a aac -shortest -pix_fmt yuv420p "tmp.slide.mp4"

Correct syntax for ffmpeg filter combination?

I'm playing with ffmpeg to generate a pretty video out of an mp3 + jpg.
I've managed to generate a video that takes a jpg as a background, and adds a waveform complex filter on top of it (and removes the black bg as an overlay).
This works:
ffmpeg -y -i 1.mp3 -loop 1 -i 1.jpg -filter_complex "[0:a]showwaves=s=1280x720:mode=cline,colorkey=0x000000:0.01:0.1,format=yuva420p[v];[1:v][v]overlay[outv]" -map "[outv]" -pix_fmt yuv420p -map 0:a -c:v libx264 -c:a copy -shortest output.mp4
I've been trying to add text somewhere in the generated video too. I'm trying the drawtext filter. I can't get this to work however, so it seems I don't understand the syntax, or how to combine filters.
This doesn't work:
ffmpeg -y -i 1.mp3 -loop 1 -i 1.jpg -filter_complex "[0:a]showwaves=s=1280x720:mode=line,colorkey=0x000000:0.01:0.1,format=yuva420p[v];[1:v][v]overlay[outv]" -filter_complex "[v]drawtext=text='My custom text test':fontcolor=White#0.5: fontsize=30:font=Arvo:x=(w-text_w)/5:y=(h-text_h)/5[out]" -map "[outv]" -pix_fmt yuv420p -map 0:a -c:v libx264 -c:a copy -shortest output.mp4
Would love some pointers!
Filteres operating in series should be chained together
ffmpeg -y -i 1.mp3 -loop 1 -i 1.jpg \
-filter_complex "[0:a]showwaves=s=1280x720:mode=line,colorkey=0x000000:0.01:0.1,
format=yuva420p[v];
[1:v][v]overlay,
drawtext=text='My custom text test':fontcolor=White#0.5:
fontsize=30:font=Arvo:x=(w-text_w)/5:y=(h-text_h)/5[outv]"
-map "[outv]" -pix_fmt yuv420p -map 0:a -c:v libx264 -c:a copy -shortest output.mp4
(You applied the drawtext onto the output of showwaves; it can be directly applied on the overlay output)

ffmpeg - how to pan left on an image

I have a command that works well to pan right on an image:
ffmpeg -nostdin -loop 1 -i image0.jpg -filter_complex "[0:v]crop=ih:ih:iw/2*t/20:0,trim=duration=5,scale=-2:720" -c:a copy -pix_fmt yuv420p output.mp4
but I can't find what would be the equivalent to pan right. I tried something like this
ffmpeg -nostdin -loop 1 -i image0.jpg -filter_complex "[0:v]crop=ih:ih:iw/2-t*20:0,trim=duration=5,scale=-2:720" -c:a copy -pix_fmt yuv420p output.mp4
but it's not giving good results
Use
ffmpeg -nostdin -loop 1 -i image0.jpg -filter_complex "[0:v]crop=ih:ih:iw-ih-(iw-ih)*t/20:0,trim=duration=5,scale=-2:720" -c:a copy -pix_fmt yuv420p output.mp4
You have to set an initial offset, mine is iw-ih and then subtract an argument which expresses movement in time, here (iw-ih)*t/20

FFmpeg First 2 Seconds of Video Not Showing

This code works fine for some audio files (makes a slideshow of JPG pictures with a PNG watermark and MP3 audio, while maintaining aspect ratio) but for this audio file, the pictures are not showing for the first two seconds or so of the video:
ffmpeg -y -framerate 1/12 -i "media/%03d.jpg" -i "media/audio.mp3" -loop 1 -i "media/watermark.png" -filter_complex "[0:v]scale=iw*min(3840/iw\,2160/ih):ih*min(3840/iw\,2160/ih), pad=3840:2160:(3840-iw)/2:(2160-ih)/2[ss]; [ss][2:v] overlay=main_w-overlay_w-10:main_h-overlay_h-10:shortest=1[out]" -map "[out]" -map 1:a -c:v libx264 -r 24 -preset veryfast -tune stillimage -pix_fmt yuv420p -c:a copy -map_metadata -1 "media/video.mkv" -report
I tried converting the audio into different formats of MP3, tried changing bitrates, changed audio to stereo, and even tried converting it to a WAV. None of these things worked.
Here are the report results for when I run this command.
If it makes a difference, I'm using Ubuntu 14.04 and FFmpeg version N-77455-g4707497 (latest version).
This command should work, but I consider this bizarre behaviour as FFmpeg should be automatically padding frames as per output spec
ffmpeg -y -framerate 1/12 -i "media/%03d.jpg" -i "media/audio.mp3" -loop 1 -i "media/watermark.png" -filter_complex "[0:v]scale=iw*min(3840/iw\,2160/ih):ih*min(3840/iw\,2160/ih), pad=3840:2160:(3840-iw)/2:(2160-ih)/2,fps=24[ss]; [ss][2:v] overlay=main_w-overlay_w-10:main_h-overlay_h-10:shortest=1[out]" -map "[out]" -map 1:a -c:v libx264 -r 24 -preset veryfast -tune stillimage -pix_fmt yuv420p -c:a copy -map_metadata -1 "media/video.mkv"

Resources