FFmpeg make video from figures and speed up a chosen part - ffmpeg

Make a video from a series of 100 figures
ffmpeg -framerate 10 -i input_figure%01d.png out.mp4
How can I only make figure numbers from [0-49] with a slower speed like -framerate 5?
My try is
ffmpeg -start_number 1 -framerate 5 -i input_figure%01d.png -vframes 49 \
-start_number 50 -framerate 10 -i input_figure%01d.png \
out.mp4
Doesn't work

The naive method is to create videos in parts, then concat them togother
ffmpeg -framerate 5 -i input_fig%01d.png -vframes 49 part_1.mp4
ffmpeg -start_number 50 -framerate 10 -i input_fig%01d.png part_2.mp4
ffmpeg -f concat -safe 0\
-i <(for f in ./part_*.mp4; do echo "file '$PWD/$f'"; done)\
-c copy out.mp4
rm part_*.mp4

Related

ffmpeg - Sync Audio with image position (Audio Slideshow)

How can i start the audio Files at the same position as the pictures? (This is for a Image slideShow with changing Audio)
ffmpeg -loop 1 -t 19 -i 1.jpg -loop 1 -t 19 -i 2.jpg -i 1.mp3 -i 2.mp3
-filter_complex "
[0:a]adelay=19s:all=1[1a];
[1:a]adelay=24s:all=1[2a];
[0:v]scale=1280:720,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[0p];
[1:v]scale=1280:720,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[1p];
[0p][1p]xfade=transition=fade:duration=1:offset=19[1x];
-map [1x] -c:v libx264 -c:a copy -t 39 out.mp4
ok i found a solution to position audio files by seconds with Images.
just use this structure
and Paramter "adelay" for an audio offset
ffmpeg -loop 1 -t 10 -i "1.jpg" -loop 1 -t 10
-i "2.jpg" -t 5 -ss 0 -i "audio1.mp3"
-t 10 -ss 10 -i "audio2.mp3"
-filter_complex "[2]adelay=1000:all=1[a1];
[3]adelay=2000:all=1[a2];
[0:v]scale=1280:720,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[0p];
[1:v]scale=1280:720,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1[1p];
[0p][1p]xfade=transition=fade:duration=1:offset=5.485[1x];
[a1][a2]amix=inputs=2[aout]" -map [1x] -map [aout] _out.mp4 -y 2>&1

FFmpeg - combine 2 commands

I have 2 commands as listed below.
Add intro image to a video
ffmpeg -y -loop 1 -framerate 10 -t 3 -i intro.png -i video.mp4 -filter_complex "[0:0] [1:0] concat=n=2:v=1:a=0" -c:v libx264 -crf 23 videoWithIntro.mp4
Add watermark to video
ffmpeg -y -i video.mp4 -i watermark_color.png -filter_complex "overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2" videoWithWatermark.mp4
I was wondering is it possible to combine these into the 1 command?
Use
ffmpeg -y -loop 1 -framerate 10 -t 3 -i intro.png -i video.mp4 -i watermark_color.png -filter_complex "[0][1]concat=n=2:v=1:a=0[v];[v][2]overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2" videoWithWatermark.mp4
I assume your videos don't have audio, else use
ffmpeg -y -loop 1 -framerate 10 -t 3 -i intro.png -i video.mp4 -i watermark_color.png -f lavfi -t 3 -i anullsrc -filter_complex "[0][1]concat=n=2:v=1:a=0[v];[v][2]overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2;[3][1]concat=n=2:v=0:a=1" videoWithWatermark.mp4
The final command to get this working correctly is as follows
ffmpeg -y -loop 1 -framerate 25 -t 3 -i 1920x1080_intro.png -i DSC_0002.MOV -i watermark_color.png -report -an -filter_complex "[1][2]overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2,setsar=1[v];[0]setsar=1[pre];[pre][v]concat=n=2:v=1:a=0" ../testing/videoWithIntroAndWatermark.mp4

Merge videos and images using ffmpeg

I'm trying to compile one .webm file that contains this:
10 seconds showing image1.jpg
Show a movie (an .mp4 file), which lasts about 20 seconds
10 seconds showing image2.jpg
10 seconds showing image3.jpg
I was unable to find out how/if the concatenate functionality of ffmpeg could do such a thing. Any clues?
You can use the concat filter.
Without audio
ffmpeg \
-loop 1 -framerate 24 -t 10 -i image1.jpg \
-i video.mp4 \
-loop 1 -framerate 24 -t 10 -i image2.jpg \
-loop 1 -framerate 24 -t 10 -i image3.jpg \
-filter_complex "[0][1][2][3]concat=n=4:v=1:a=0" out.mp4
Match -framerate with frame rate from video.mp4.
With audio
If there is audio in video.mp4 you'll need to provide audio for the images as well for it to be able to concatenate. Example of generating silence:
ffmpeg \
-loop 1 -framerate 24 -t 10 -i image1.jpg \
-i video.mp4 \
-loop 1 -framerate 24 -t 10 -i image2.jpg \
-loop 1 -framerate 24 -t 10 -i image3.jpg \
-f lavfi -t 0.1 -i anullsrc=channel_layout=stereo:sample_rate=44100 \
-filter_complex "[0:v][4:a][1:v][1:a][2:v][4:a][3:v][4:a]concat=n=4:v=1:a=1" out.mp4
Match channel_layout with audio channel layout (stereo, mono, 5.1, etc) from video.mp4.
Match sample_rate with audio sample rate from video.mp4.
No need to match the -t duration from anullsrc with any associated video input: the concat filter will automatically pad it to match video duration.

Ffmpeg show an image for multiple seconds before a video without re-encoding

I've been looking all around for this. Problem is that most google searches end up with being about creating a video from solely PNG files.
I've found this command which does the job :
ffmpeg -y -loop 1 -framerate 60 -t 5 -i firstimage.jpg -t 5 -f lavfi -i aevalsrc=0 -loop 1 -framerate 60 -t 5 -i secondimage.png -t 5 -f lavfi -i aevalsrc=0 -loop 1 -framerate 60 -t 5 -i thirdimage.png -t 5 -f lavfi -i aevalsrc=0 -i "shadowPlayVid.mp4" -filter_complex "[0:0][1:0][2:0][3:0][4:0][5:0][6:0][6:1] concat=n=4:v=1:a=1 [v] [a]" -map [v] -map [a] output.mp4 >> log_file1.txt 2>&1
But it seems to reencode the whole video, the input video is H.264 without CFR, but it seems to me that putting just some images before the video shouldn't take too long.
Because it ends up encoding the whole thing, this takes about 2 hours with a video of 30 minutes on a strong computer, while I feel like without encoding this should be able to be done much quicker. How do I make sure it doesn't re-encode while maintaining every image showing for 5 seconds first?
Generate your playervid.mp4 via
ffmpeg -y -loop 1 -framerate 60 -t 5 -i sample-out3.jpg -f lavfi -t 5 -i aevalsrc=0 -vf settb=1/60000 -video_track_timescale 60000 -c:v libx264 -pix_fmt yuv420p playervid.mp4

How do I add 2 more pictures to this ffmpeg slideshow?

This is the command I use to make the slideshow with ffmpeg:
ffmpeg -y -i audio.wav -framerate 1/4 -t 60 -loop 1 -i first.png -framerate 1/4 -t 600 -loop 1 -i Test.png -framerate 1/4 -t 600 -loop 1 -i test-ceinture-running-flip-belt.png -framerate 1/4 -t 600 -loop 1 -i Wikimedia_Outreach_test_logo.png -filter_complex "[1:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v0]; [2:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v1]; [3:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v2]; [4:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v3]; [v0][v1][v2][v3]concat=n=4:v=1:a=0 [out]" -map "[out]" -map 0:0 -c:a libvo_aacenc -b:a 128k -vcodec mpeg4 -qscale:v 20 -keyint_min 100 -f mp4 -r 10 -pix_fmt yuv420p out_024.mp4
I would like to add 2 more pictures that lasts 600 seconds each.
Could you please help me?
Well, why don't you experiment manipulating your current command? everything is there. According to your approach you can achieve this as follows.
ffmpeg -y -i audio.wav -framerate 1/4 -t 60 -loop 1 -i first.png -framerate 1/4 -t 600 -loop 1 -i Test.png -framerate 1/4 -t 600 -loop 1 -i test-ceinture-running-flip-belt.png -framerate 1/4 -t 600 -loop 1 -i Wikimedia_Outreach_test_logo.png -framerate 1/4 -t 600 -loop 1 -i new_image_1.png -framerate 1/4 -t 600 -loop 1 -i new_image_2.png -filter_complex "
[1:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v0];
[2:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v1];
[3:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v2];
[4:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v3];
[5:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v4];
[6:v]scale=iw*min(1280/iw\,720/ih):ih*min(1280/iw\,720/ih),pad=1280:720:0+(1280-iw*min(1280/iw\,720/ih))/2:0+(720-ih*min(1280/iw\,720/ih))/2 [v5];
[v0][v1][v2][v3][v4][v5]concat=n=6:v=1:a=0 [out]" -map "[out]" -map 0:0 -c:a libvo_aacenc -b:a 128k -vcodec mpeg4 -qscale:v 20 -keyint_min 100 -f mp4 -r 10 -pix_fmt yuv420p out_024.mp4
But the way you have done this is not efficient. You may need to reed the relevant documentation first. You can rename the image files with common settings like -framerate 1/4 -t 600 to something like img%03d.png. It will help you to reduce the command length as well as the performance aspect at the execution.
Hope this helps!

Resources