ffmpeg multiple text/logo elements - ffmpeg

I am trying to add multiple items to an ffmpeg command and am getting stuck.
So far in the command I am automatically updating one image, which I'm using as a video, I also want to add a logo and two lines of text.
I have been successful until the last item, which is the logo overlay.
This is the relevant part of code:
ffmpeg \
-f image2 -loop 1 \
-y \
-i "/var/www/html/image_rotate.png" \
-re \
-i audio.mp3 \
-vf "movie=/var/www/html/overlay_logo.png [watermark]; [in][watermark] overlay=0:0 [out], drawtext=fontsize=10:fontfile=/var/www/html/OpenSans-Regular.ttf:textfile=/var/www/html/text1.txt:box=1:boxcolor=#000000:fontcolor=#FFFFFF:x=0:y=(h-text_h-20):reload=1, drawtext=fontsize=10:fontfile=/var/www/html/OpenSans-Regular.ttf:textfile=/var/www/htmltext2.txt:box=1:boxcolor=#000000:fontcolor=#FFFFFF:x=0:y=(h-text_h-30)" \
This gives me the following error:
Simple filtergraph ... was expected to have exactly 1 input and 1 output. However, it had >1 input(s) and >1 output(s). Please adjust, or use a complex filtergraph (-filter_complex) instead.
If I remove the last part I added (the overlay logo) I do not get the error.
If I add multiple -vf it only processes one (the text OR the logo).
I'm not sure how to achieve this.

When you need to work with multiple streams while filtering, the recommended method is to use a filter_complex.
ffmpeg \
-loop 1 \
-i "/var/www/html/image_rotate.png" \
-i "/var/www/html/overlay_logo.png" \
-i audio.mp3 \
-filter_complex "[0][1]overlay=0:0,drawtext=fontsize=10:fontfile=/var/www/html/OpenSans-Regular.ttf:textfile=/var/www/html/text1.txt:box=1:boxcolor=#000000:fontcolor=#FFFFFF:x=0:y=(h-text_h-20):reload=1, drawtext=fontsize=10:fontfile=/var/www/html/OpenSans-Regular.ttf:textfile=/var/www/htmltext2.txt:box=1:boxcolor=#000000:fontcolor=#FFFFFF:x=0:y=(h-text_h-30)" \
-y \
-shortest \
The logo is now fed as a regular input.

Related

overlay multiple images on a video with specific time per image and repeat (loop) the process the images until video end

I am trying to making video with ffmpeg where I want to overlay images on a video.
I want to show the image for 5 secound each and want to the process to loop until the video end.
I am using following commend which working perfectly but want to modify to loop the images.
ffmpeg -y -i long_process/2-scrolling.mp4 \
-i upload-images/040820221255452.png \
-i upload-images/040820221255453.png \
-filter_complex "[0:v][1:v]overlay=75:(H-h)/2:enable='between(t, 1, 5)'[v0]; \
[v0][2:v]overlay=75:(H-h)/2:enable='between(t, 5, 10)'" \
-c:a copy long_process/output.mp4
I am very new to ffmpeg looking for help from you.
Thanks in advance
I got the answer
ffmpeg -y -i long_process/2-scrolling.mp4 -framerate 1/3 -pattern_type glob -loop 1 -i 'tools/*.png' \
-filter_complex "[0]overlay=75:(H-h)/2:shortest=1" \
-r 60 -c:a copy long_process/output.mp4

FFMPEG trimming video (using select between) doesn't affect overall duration

Completely new to working with FFMPEG, what I'm trying to achieve is applying overlaying graphics at certain positions and times, and cutting out sections of a single input video.
I've worked out the overlaying graphics, so this code is working:
ffmpeg -i /Users/username/projectdir/static/video.mp4 \
-i overlay.png -i overlay2.png \
-filter_complex "[0:v][1:v] overlay=192:108:enable='between(t, 0, 5)'[ov0];
[ov0] overlay=192:108:enable='between(t, 5, 10)'" \
-pix_fmt yuv420p output_overlayed.mp4
But when I try to cut out sections using this code:
ffmpeg -i /Users/username/projectdir/static/video.mp4 \
-i overlay.png -i overlay2.png \
-filter_complex "[0:v][1:v] overlay=192:108:enable='between(t, 0, 5)'[ov0]; \
[ov0] overlay=192:108:enable='between(t, 5, 10)', \
select='between(t,0,5)+between(t,10,15)', \
setpts='N/FRAME_RATE/TB'" \
-pix_fmt yuv420p output_overlayed_trimmed.mp4
It seems to cut correctly, so the original video starts playing from 0 seconds until 5 seconds and then plays from 10 seconds in until 15 seconds and cuts out. But after the point where the video cuts out it's just a black screen for the duration of the video. I can't seem to get it to work so it affects the overall duration of the video.
(The values being passed in are just examples by the way, eg. I've got it to start an overlay 5 seconds in but also cut 5 seconds in)
I have the timestamps for when the overlays should appear on the non-trimmed video, so the overlaying should happen first and then the trimming. If the video is trimmed first then the overlays will appear at the wrong times.
An alternative way of achieving this that is currently working is by performing the first line of code (which just produces a new video file with the overlay) and then separately take this new file and perform the trimming independently:
ffmpeg -ss 0 -to 5 -i /Users/username/projectdir/static/output_overlayed.mp4 \
-ss 15 -to 20 -i /Users/username/projectdir/static/output_overlayed.mp4 \
-filter_complex "[0][1]concat=n=2:v=1:a=1" output_trimmed.mp4
But this means working with 2 separate files and then having to remove the first after the 2nd execution is complete. Ideally I'd combine them into one command which doesn't produce multiple files.
Would appreciate any help - thanks!
How about get the input twice with different trims (so both video & audio are cut in sync) then concatenate after overlaying? Like this:
ffmpeg -t 5 -i /Users/username/projectdir/static/video.mp4 \
-ss 10 -to 15 -i /Users/username/projectdir/static/video.mp4 \
-i overlay.png -i overlay2.png \
-filter_complex "[0:v][2:v] overlay=192:108[ov0]; \
[1:v][3:v] overlay=192:108[ov1]; \
[ov0][0:a][ov1][1:a] concat=n=2:v=2:a=2[vout][aout] \
-map [vout] -map[aout] -pix_fmt yuv420p output_overlayed_trimmed.mp4

how to add multi animation for one image when create video using ffmpeg

I are using ffmpeg to create video from many images.
Example I'm using command below to create 1 video.
Sample Command.
ffmpeg \
-loop 1 -t 5 -i img001.jpeg \
-loop 1 -t 5 -i img002.jpeg \
-loop 1 -t 5 -i img003.jpeg \
-loop 1 -t 5 -i img004.jpeg \
-loop 1 -t 5 -i img005.jpeg \
-filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=out:st=4:d=1[v0]; \
[1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v1]; \
[2:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v2]; \
[3:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v3]; \
[4:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1,fade=t=in:st=0:d=1,fade=t=out:st=4:d=1[v4]; \
[v0][v1][v2][v3][v4]concat=n=5:v=1:a=0,format=yuv420p[v]" -map "[v]" out.mp4
But I'm having a problem. For example, image001.png, I only know add single animation for this image when creating the video.
How do I add multi animation to an image? For example, rotate, move from top to center, then from center to right.
Thankyou very much.

ffmpeg How to make timed picture overlay changes that repeat

Hello I am working to figure out how to make it so that my live stream has logos that change into another logo every 20 seconds currently all I have been able to figure out is how to enable them at a certain time like this.
ffmpeg -re -i "https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8" -i ./public/images/ACE.png -i ./public/images/logo2.jpg -i ./public/images/crunchy.png -i ./public/images/red.jpg -filter_complex \
"[0]scale=1290:720,setsar=1[ovrl0]; \
[1]scale=40:40[ovrl1]; \
[2]scale=40:40[ovrl2]; \
[3]scale=40:40[ovrl3]; \
[4]scale=40:40[ovrl4]; \
[ovrl0][ovrl1] overlay=x=(main_w-overlay_w)/1.025:y=(main_h-overlay_h)/18:enable='lt(mod(t,40),10)'[v1]; \
[v1][ovrl2] overlay=x=(main_w-overlay_w)/1.025:y=(main_h-overlay_h)/18:enable='between(mod(t,40),10,20)'[v2]; \
[v2][ovrl3] overlay=x=(main_w-overlay_w)/1.025:y=(main_h-overlay_h)/18:enable='gt(mod(t,40),20)'[v3]; \
[v3][ovrl4] overlay=x=(main_w-overlay_w)/1.025:y=(main_h-overlay_h)/18:enable='gt(mod(t,40),30)'" -acodec aac -vcodec libx264 -f flv "rtmp://a.rtmp.youtube.com/live2/2222-2222-2222-2222"
Set enable for first logo overlay to lt(mod(t,40),20), and for 2nd logo overlay to gte(mod(t,40),20).
This will show 1st logo at t = 0-20,40-60,80-100.. and 2nd logo at t = 20-40,60-80,100-120..

how to fade two images with ffmpeg

I have two images and I want to create a simple fading transition between them.
I also want the final output to be a sequence of images rather than a video?
So if the fading transition was 10 frames long I'd want the output to be a sequence of 10 images.
How can I achieve this with ffmpeg?
See the blend video filter:
ffmpeg -loop 1 -i input0.png -loop 1 -i input1.png -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,3),1,T/3))+B*(1-(if(gte(T,3),1,T/3)))'" -t 4 frames_%04d.png
This example will make a 3 second cross-fade of input1.png over input0.png.
To crossfade/dip-to-black multiple images see Create video with 5 images with fade-in/out effect in ffmpeg.
To the best of my knowledge you cannot achieve this just with ffmpeg. Please take a look at MLT framework if you want to do it in scriprs; take a look at openshot if you want an interactive app.
Try this:
ffmpeg \
-loop 1 -t 3 -i input1.png \
-loop 1 -t 3 -i input2.png \
-loop 1 -t 3 -i input3.png \
-loop 1 -t 3 -i input4.png \
-loop 1 -t 3 -i input5.png \
-filter_complex \
"[1:v][0:v]blend=all_expr='A*(if(gte(T,3),1,T/3))+B*(1-(if(gte(T,3),1,T/3)))'[v0]; \
[2:v][1:v]blend=all_expr='A*(if(gte(T,3),1,T/3))+B*(1-(if(gte(T,3),1,T/3)))'[v1]; \
[3:v][2:v]blend=all_expr='A*(if(gte(T,3),1,T/3))+B*(1-(if(gte(T,3),1,T/3)))'[v2]; \
[4:v][3:v]blend=all_expr='A*(if(gte(T,3),1,T/3))+B*(1-(if(gte(T,3),1,T/3)))'[v3]; \
[v0][v1][v2][v3]concat=n=4:v=1:a=0[v]"
-map "[v]" out.mp4
Haven't tried with images, but you could try -t 12 frames_%04d.png at the end or whatever.

Resources