<p>I am creating a video with audio that consists of 25 images that fade into each other for the duration of an audio file. There is also some text that will appear on the finished video.</p>
<p>What I currently have works but it is terrible slow. On an AMD 3500x using all 6 cores it can only get between .9 and 1.1 frames per second using libx264 to encode a mp4 file. Using h264_nvenc I can only get slightly better at 1.1 to 1.3 frames per second. I am going to be making 100's of these videos so would really like to do it as efficiently as possible.</p>
<p>It seems to be the fades that cause the problem as I can encode at 7 to 12 fps if it just jumps from one image to the other without the fade. And it seems cuda doesn't have anything that can speed up the image processing.</p>
<p>Here is what I have that works but I'm sure it can be made more compact. I have tried different things like setting a time -t to the input of each image but that didn't help. I have tried doing just a fade in over the previous image instead of a fade out then the next image fading in. My thinking was half as many filters would make it faster but it didn't change the speed of encoding at all.</p>
<pre><code>#!/bin/bash
    
full_path=&quot;/Videos&quot;
a_path=$full_path&quot;/&quot;$1&quot;/&quot;$2&quot;.wav&quot;
    
images=25
    
duration_function() {
    ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $a_path
        return 100
    }
    
duration=&quot;$(duration_function &quot;$a_path&quot;)&quot; 
   
duration=${duration%.*}
minutes=$((duration / 60))
seconds=$((duration / 60))
seconds=$(printf &quot;%02d&quot; $seconds)
fade=$((duration / images))
 

intro1=1
intro2=$((fade+2))
intro3=$((intro2+fade))
intro4=$((intro3+fade))
intro5=$((intro4+fade))
intro6=$((intro5+fade))
intro7=$((intro6+fade))
intro8=$((intro7+fade))
intro9=$((intro8+fade))
intro10=$((intro9+fade))
intro11=$((intro10+fade))
intro12=$((intro11+fade))
intro13=$((intro12+fade))
intro14=$((intro13+fade))
intro15=$((intro14+fade))
intro16=$((intro15+fade))
intro17=$((intro16+fade))
intro18=$((intro17+fade))
intro19=$((intro18+fade))
intro20=$((intro19+fade))
intro21=$((intro20+fade))
intro22=$((intro21+fade))
intro23=$((intro22+fade))
intro24=$((intro23+fade))
intro25=$((intro24+fade))

outro1=$((fade+2))
outro2=$((outro1+fade))
outro3=$((outro2+fade))
outro4=$((outro3+fade))
outro5=$((outro4+fade))
outro6=$((outro5+fade))
outro7=$((outro6+fade))
outro8=$((outro7+fade))
outro9=$((outro8+fade))
outro10=$((outro9+fade))
outro11=$((outro10+fade))
outro12=$((outro11+fade))
outro13=$((outro12+fade))
outro14=$((outro13+fade))
outro15=$((outro14+fade))
outro16=$((outro15+fade))
outro17=$((outro16+fade))
outro18=$((outro17+fade))
outro19=$((outro18+fade))
outro20=$((outro19+fade))
outro21=$((outro20+fade))
outro22=$((outro21+fade))
outro23=$((outro22+fade))
outro24=$((outro23+fade))
outro25=$((duration-1))


/usr/bin/ffmpeg -y -hide_banner -threads 6 -f lavfi -i color=c=black:s=3840x2160:r=30:d=$duration -pix_fmt rgba -loop 1 -i 1.png -loop 1 -i 2.png -loop 1 -i 3.png -loop 1 -i 4.png -loop 1 -i 5.png -loop 1 -i 6.png -loop 1 -i 7.png -loop 1 -i 8.png -loop 1 -i 9.png -loop 1 -i 10.png -loop 1 -i 11.png -loop 1 -i 12.png -loop 1 -i 13.png -loop 1 -i 14.png -loop 1 -i 15.png -loop 1 -i 16.png -loop 1 -i 17.png -loop 1 -i 18.png -loop 1 -i 19.png -loop 1 -i 20.png -loop 1 -i 21.png -loop 1 -i 22.png -loop 1 -i 23.png -loop 1 -i 24.png -loop 1 -i 25.png -i $a_path -filter_complex \
&quot;[1]format=rgba,fade=in:st=$intro1:d=0.5:alpha=1,fade=out:st=$outro1:d=0.5:alpha=1[1a];\
[0:v][1a]overlay=x=0:y=0[out];\
[2]format=rgba,fade=in:st=$intro3:d=0.5:alpha=1,fade=out:st=$outro3:d=0.5:alpha=1[2a];\
[out][2a]overlay=x=0:y=0[out];\
[3]format=rgba,fade=in:st=$intro3:d=0.5:alpha=1,fade=out:st=$outro3:d=0.5:alpha=1[3a];\
[out][3a]overlay=x=0:y=0[out];\
[4]format=rgba,fade=in:st=$intro4:d=0.5:alpha=1,fade=out:st=$outro4:d=0.5:alpha=1[4a];\
[out][4a]overlay=x=0:y=0[out];\
[5]format=rgba,fade=in:st=$intro5:d=0.5:alpha=1,fade=out:st=$outro5:d=0.5:alpha=1[5a];\
[out][5a]overlay=x=0:y=0[out];\
[6]format=rgba,fade=in:st=$intro6:d=0.5:alpha=1,fade=out:st=$outro6:d=0.5:alpha=1[6a];\
[out][6a]overlay=x=0:y=0[out];\
[7]format=rgba,fade=in:st=$intro7:d=0.5:alpha=1,fade=out:st=$outro7:d=0.5:alpha=1[7a];\
[out][7a]overlay=x=0:y=0[out];\
[8]format=rgba,fade=in:st=$intro8:d=0.5:alpha=1,fade=out:st=$outro8:d=0.5:alpha=1[8a];\
[out][8a]overlay=x=0:y=0[out];\
[9]format=rgba,fade=in:st=$intro9:d=0.5:alpha=1,fade=out:st=$outro9:d=0.5:alpha=1[9a];\
[out][9a]overlay=x=0:y=0[out];\
[10]format=rgba,fade=in:st=$intro10:d=0.5:alpha=1,fade=out:st=$outro10:d=0.5:alpha=1[10a];\
[out][10a]overlay=x=0:y=0[out];\
[11]format=rgba,fade=in:st=$intro11:d=0.5:alpha=1,fade=out:st=$outro11:d=0.5:alpha=1[11a];\
[out][11a]overlay=x=0:y=0[out];\
[12]format=rgba,fade=in:st=$intro12:d=0.5:alpha=1,fade=out:st=$outro12:d=0.5:alpha=1[12a];\
[out][12a]overlay=x=0:y=0[out];\
[13]format=rgba,fade=in:st=$intro13:d=0.5:alpha=1,fade=out:st=$outro13:d=0.5:alpha=1[13a];\
[out][13a]overlay=x=0:y=0[out];\
[14]format=rgba,fade=in:st=$intro14:d=0.5:alpha=1,fade=out:st=$outro14:d=0.5:alpha=1[14a];\
[out][14a]overlay=x=0:y=0[out];\
[15]format=rgba,fade=in:st=$intro15:d=0.5:alpha=1,fade=out:st=$outro15:d=0.5:alpha=1[15a];\
[out][15a]overlay=x=0:y=0[out];\
[16]format=rgba,fade=in:st=$intro16:d=0.5:alpha=1,fade=out:st=$outro16:d=0.5:alpha=1[16a];\
[out][16a]overlay=x=0:y=0[out];\
[17]format=rgba,fade=in:st=$intro17:d=0.5:alpha=1,fade=out:st=$outro17:d=0.5:alpha=1[17a];\
[out][17a]overlay=x=0:y=0[out];\
[18]format=rgba,fade=in:st=$intro18:d=0.5:alpha=1,fade=out:st=$outro18:d=0.5:alpha=1[18a];\
[out][18a]overlay=x=0:y=0[out];\
[19]format=rgba,fade=in:st=$intro19:d=0.5:alpha=1,fade=out:st=$outro19:d=0.5:alpha=1[19a];\
[out][19a]overlay=x=0:y=0[out];\
[20]format=rgba,fade=in:st=$intro20:d=0.5:alpha=1,fade=out:st=$outro20:d=0.5:alpha=1[20a];\
[out][20a]overlay=x=0:y=0[out];\
[21]format=rgba,fade=in:st=$intro21:d=0.5:alpha=1,fade=out:st=$outro21:d=0.5:alpha=1[21a];\
[out][21a]overlay=x=0:y=0[out];\
[22]format=rgba,fade=in:st=$intro22:d=0.5:alpha=1,fade=out:st=$outro22:d=0.5:alpha=1[22a];\
[out][22a]overlay=x=0:y=0[out];\
[23]format=rgba,fade=in:st=$intro23:d=0.5:alpha=1,fade=out:st=$outro23:d=0.5:alpha=1[23a];\
[out][23a]overlay=x=0:y=0[out];\
[24]format=rgba,fade=in:st=$intro24:d=0.5:alpha=1,fade=out:st=$outro24:d=0.5:alpha=1[24a];\
[out][24a]overlay=x=0:y=0[out];\
[25]format=rgba,fade=in:st=$intro25:d=0.5:alpha=1,fade=out:st=$outro25:d=0.5:alpha=1[25a];\
[out][25a]overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)[out];[out]drawtext=fontfile=/font.ttf:text='Text':fontcolor=white:fontsize=50:box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1810,\
drawtext=fontfile=/font.ttf:text='\:':fontcolor=red:fontsize=50:box=1:boxcolor=black@0:boxborderw=5:x=762:y=1813:enable='lt(mod(t,1),.5)',\
drawtext=fontfile=/font.ttf:fontsize=50:fontcolor=white:text='Elapsed Time  %{pts\:gmtime\:0\:%M\\\\\:%S} / $minutes\:$seconds':box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1860,
drawtext=fontfile=/font.ttf:fontsize=50:fontcolor=red:text='\:':box=1:boxcolor=black@.4:boxborderw=9:x=823:y=1865:enable='lt(mod(t,1),.4)',
drawtext=fontfile=/font.ttf:text='Text':y=1712:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=white:fontsize=85:enable='between(t,0,$((duration-1)))',\
drawtext=fontfile=/font.ttf:text='Text':y=1711:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=red:fontsize=85:enable='between(t,0,$((duration-1)))'[out]&quot;\
 -map &quot;[out]&quot; -map 26:a -c:v libx264 -crf 18  -acodec aac video.mp4
</code></pre>
<p>So I'm not sure if setting a color format would help or what I can do. I know it is 4k and will be slow but for most of the video all it really needs to do is display a static picture but it seem like because there is an alpha channel it slows it way doing even it the transparency for most of the frames is at 0%.</p>
<p>Thank you to anyone who can help me make this more efficient!</p>
<p>Thanks to the helpful links provided I ended up with this and it runs at over 20 fps and looks great. I wish I could get the cuda HW acceleration to work but I couldn't figure out the hwupload hwdoanload and told me the pixel formats were incompatable but I am very happy with this!</p>
<pre><code>#!/bin/bash

full_path=&quot;/Videos&quot;
a_path=$full_path&quot;/&quot;$1&quot;/&quot;$2&quot;.wav&quot;
font=&quot;/font.ttf&quot;
images=25

duration_function() {
    ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $a_path
    return 100
}

duration=&quot;$(duration_function &quot;$a_path&quot;)&quot; 
duration=${duration%.*}

minutes=$((duration / 60))
seconds=$((duration % 60))

seconds=$(printf &quot;%02d&quot; $seconds)
fade=$((duration / images))

intro1=1
intro2=$((intro1+fade))
intro3=$((intro2+fade))
intro4=$((intro3+fade))
intro5=$((intro4+fade))
intro6=$((intro5+fade))
intro7=$((intro6+fade))
intro8=$((intro7+fade))
intro9=$((intro8+fade))
intro10=$((intro9+fade))
intro11=$((intro10+fade))
intro12=$((intro11+fade))
intro13=$((intro12+fade))
intro14=$((intro13+fade))
intro15=$((intro14+fade))
intro16=$((intro15+fade))
intro17=$((intro16+fade))
intro18=$((intro17+fade))
intro19=$((intro18+fade))
intro20=$((intro19+fade))
intro21=$((intro20+fade))
intro22=$((intro21+fade))
intro23=$((intro22+fade))
intro24=$((intro23+fade))
intro25=$((intro24+fade))

ffmpeg -y -hide_banner -threads 6 -f lavfi -i color=c=black:s=3840x2160:r=25:d=$duration -loop 1 -i 1.png -loop 1 -i 2.png -loop 1 -i 3.png -loop 1 -i 4.png -loop 1 -i 5.png -loop 1 -i 6.png -loop 1 -i 7.png -loop 1 -i 8.png -loop 1 -i 9.png -loop 1 -i 10.png -loop 1 -i 11.png -loop 1 -i 12.png -loop 1 -i 13.png -loop 1 -i 14.png -loop 1 -i 15.png -loop 1 -i 16.png -loop 1 -i 17.png -loop 1 -i 18.png -loop 1 -i 19.png -loop 1 -i 20.png -loop 1 -i 21.png -loop 1 -i 22.png -loop 1 -i 23.png -loop 1 -i 24.png -loop 1 -i 25.png -i $a_path -filter_complex &quot;\
[0:v][1]xfade=transition=fade:duration=2:offset=$intro1[out];\
[out][2]xfade=transition=fade:duration=2:offset=$intro2[out];\
[out][3]xfade=transition=fade:duration=2:offset=$intro3[out];\
[out][4]xfade=transition=fade:duration=2:offset=$intro4[out];\
[out][5]xfade=transition=fade:duration=2:offset=$intro5[out];\
[out][6]xfade=transition=fade:duration=2:offset=$intro6[out];\
[out][7]xfade=transition=fade:duration=2:offset=$intro7[out];\
[out][8]xfade=transition=fade:duration=2:offset=$intro8[out];\
[out][9]xfade=transition=fade:duration=2:offset=$intro9[out];\
[out][10]xfade=transition=fade:duration=2:offset=$intro10[out];\
[out][11]xfade=transition=fade:duration=2:offset=$intro11[out];\
[out][12]xfade=transition=fade:duration=2:offset=$intro12[out];\
[out][13]xfade=transition=fade:duration=2:offset=$intro13[out];\
[out][14]xfade=transition=fade:duration=2:offset=$intro14[out];\
[out][15]xfade=transition=fade:duration=2:offset=$intro15[out];\
[out][16]xfade=transition=fade:duration=2:offset=$intro16[out];\
[out][17]xfade=transition=fade:duration=2:offset=$intro17[out];\
[out][18]xfade=transition=fade:duration=2:offset=$intro18[out];\
[out][19]xfade=transition=fade:duration=2:offset=$intro19[out];\
[out][20]xfade=transition=fade:duration=2:offset=$intro20[out];\
[out][21]xfade=transition=fade:duration=2:offset=$intro21[out];\
[out][22]xfade=transition=fade:duration=2:offset=$intro22[out];\
[out][23]xfade=transition=fade:duration=2:offset=$intro23[out];\
[out][24]xfade=transition=fade:duration=2:offset=$intro24[out];\
[out][25]xfade=transition=fade:duration=2:offset=$intro25[out];\
[out]drawtext=fontfile=$font:text='Text':fontcolor=white:fontsize=50:box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1810,\
drawtext=fontfile=$font:text='\:':fontcolor=red:fontsize=50:box=1:x=762:y=1813:enable='lt(mod(t,1),.5)',\
drawtext=fontfile=$font:fontsize=50:fontcolor=white:text='Elapsed Time  %{pts\:gmtime\:0\:%M\\\\\:%S} / $minutes\:$seconds':box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1860,
drawtext=fontfile=$font:fontsize=50:fontcolor=red:text='\:':x=823:y=1865:enable='lt(mod(t,1),.4)',
drawtext=fontfile=$font:text='Text':y=1712:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=white:fontsize=85:enable='between(t,0,$((duration-1)))',\
drawtext=fontfile=$font:text='Text':y=1711:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=red:fontsize=85:enable='between(t,0,$((duration-1)))'[out]&quot;\
 -map &quot;[out]&quot; -map 26:a -shortest -c:v hevc_nvenc -rc vbr -cq 24 -qmin 24 -qmax 24 -profile:v main10 -b:v 0K -c:a aac -map 0 video.mp4
</code></pre>

CC BY-SA 4.0
2023-11-22T09:20:54.780Z
Try this. Determine the length of the audio and calculate the fade in-out length per image. Then generate 25 *individual* video files from each of the 25 images with the fade in-out effect. Then use the [ffmpeg concat demuxer](https://stackoverflow.com/questions/49371422/how-to-merge-two-videos-without-re-encoding) to merge all the 25 videos files into one video (this will join the videos together without re-encoding it). Finally [add the audio](https://superuser.com/a/590210) to the final video.
sfxedit
CC BY-SA 4.0
2023-11-22T09:26:37.043Z
See also - [3 Methods you need to know about FFmpeg transition animation](https://donglumail.medium.com/3-methods-you-need-to-know-for-ffmpeg-transition-animation-7d2ea8f7ced7) and experiment which is the fastest.
sfxedit
CC BY-SA 4.0
2023-11-22T12:46:35.087Z
Is it that ffmpeg has to calculate all the images even if only one of them is visible? I made a test with just two images thinking that was the case and even with only two images it was the same slow speed. Or would I have to make videos that were just the 1 second transitions and the 15 or so odd seconds where there was no transition would be a separate video file too. So I would need 50 videos. I could probably script that so it wouldn't be so bad. I'm not sure how to deal with the text. Some is scrolling and it takes the cues from the total length of the video & there is a elapsed counter.
Michael Ciesielczyk
CC BY-SA 4.0
2023-11-23T00:45:38.163Z
Thank you for the links! They pointed me to xfade and now I am getting over 20 fps second the quality looks great!
Michael Ciesielczyk
<ffmpeg><bash>
Most efficiant way to create a video with series of images faded in and out with ffmpeg
Michael Ciesielczyk
# Most efficiant way to create a video with series of images faded in and out with ffmpeg

(Asked by: username_0 on 2023-11-22)

I am creating a video with audio that consists of 25 images that fade into each other for the duration of an audio file. There is also some text that will appear on the finished video.
What I currently have works but it is terrible slow. On an AMD 3500x using all 6 cores it can only get between .9 and 1.1 frames per second using libx264 to encode a mp4 file. Using h264_nvenc I can only get slightly better at 1.1 to 1.3 frames per second. I am going to be making 100's of these videos so would really like to do it as efficiently as possible.
It seems to be the fades that cause the problem as I can encode at 7 to 12 fps if it just jumps from one image to the other without the fade. And it seems cuda doesn't have anything that can speed up the image processing.
Here is what I have that works but I'm sure it can be made more compact. I have tried different things like setting a time -t to the input of each image but that didn't help. I have tried doing just a fade in over the previous image instead of a fade out then the next image fading in. My thinking was half as many filters would make it faster but it didn't change the speed of encoding at all.
#!/bin/bash
    
full_path="/Videos"
a_path=$full_path"/"$1"/"$2".wav"
    
images=25
    
duration_function() {
    ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $a_path
        return 100
    }
    
duration="$(duration_function "$a_path")" 
   
duration=${duration%.*}
minutes=$((duration / 60))
seconds=$((duration / 60))
seconds=$(printf "%02d" $seconds)
fade=$((duration / images))
 

intro1=1
intro2=$((fade+2))
intro3=$((intro2+fade))
intro4=$((intro3+fade))
intro5=$((intro4+fade))
intro6=$((intro5+fade))
intro7=$((intro6+fade))
intro8=$((intro7+fade))
intro9=$((intro8+fade))
intro10=$((intro9+fade))
intro11=$((intro10+fade))
intro12=$((intro11+fade))
intro13=$((intro12+fade))
intro14=$((intro13+fade))
intro15=$((intro14+fade))
intro16=$((intro15+fade))
intro17=$((intro16+fade))
intro18=$((intro17+fade))
intro19=$((intro18+fade))
intro20=$((intro19+fade))
intro21=$((intro20+fade))
intro22=$((intro21+fade))
intro23=$((intro22+fade))
intro24=$((intro23+fade))
intro25=$((intro24+fade))

outro1=$((fade+2))
outro2=$((outro1+fade))
outro3=$((outro2+fade))
outro4=$((outro3+fade))
outro5=$((outro4+fade))
outro6=$((outro5+fade))
outro7=$((outro6+fade))
outro8=$((outro7+fade))
outro9=$((outro8+fade))
outro10=$((outro9+fade))
outro11=$((outro10+fade))
outro12=$((outro11+fade))
outro13=$((outro12+fade))
outro14=$((outro13+fade))
outro15=$((outro14+fade))
outro16=$((outro15+fade))
outro17=$((outro16+fade))
outro18=$((outro17+fade))
outro19=$((outro18+fade))
outro20=$((outro19+fade))
outro21=$((outro20+fade))
outro22=$((outro21+fade))
outro23=$((outro22+fade))
outro24=$((outro23+fade))
outro25=$((duration-1))


/usr/bin/ffmpeg -y -hide_banner -threads 6 -f lavfi -i color=c=black:s=3840x2160:r=30:d=$duration -pix_fmt rgba -loop 1 -i 1.png -loop 1 -i 2.png -loop 1 -i 3.png -loop 1 -i 4.png -loop 1 -i 5.png -loop 1 -i 6.png -loop 1 -i 7.png -loop 1 -i 8.png -loop 1 -i 9.png -loop 1 -i 10.png -loop 1 -i 11.png -loop 1 -i 12.png -loop 1 -i 13.png -loop 1 -i 14.png -loop 1 -i 15.png -loop 1 -i 16.png -loop 1 -i 17.png -loop 1 -i 18.png -loop 1 -i 19.png -loop 1 -i 20.png -loop 1 -i 21.png -loop 1 -i 22.png -loop 1 -i 23.png -loop 1 -i 24.png -loop 1 -i 25.png -i $a_path -filter_complex \
"[1]format=rgba,fade=in:st=$intro1:d=0.5:alpha=1,fade=out:st=$outro1:d=0.5:alpha=1[1a];\
[0:v][1a]overlay=x=0:y=0[out];\
[2]format=rgba,fade=in:st=$intro3:d=0.5:alpha=1,fade=out:st=$outro3:d=0.5:alpha=1[2a];\
[out][2a]overlay=x=0:y=0[out];\
[3]format=rgba,fade=in:st=$intro3:d=0.5:alpha=1,fade=out:st=$outro3:d=0.5:alpha=1[3a];\
[out][3a]overlay=x=0:y=0[out];\
[4]format=rgba,fade=in:st=$intro4:d=0.5:alpha=1,fade=out:st=$outro4:d=0.5:alpha=1[4a];\
[out][4a]overlay=x=0:y=0[out];\
[5]format=rgba,fade=in:st=$intro5:d=0.5:alpha=1,fade=out:st=$outro5:d=0.5:alpha=1[5a];\
[out][5a]overlay=x=0:y=0[out];\
[6]format=rgba,fade=in:st=$intro6:d=0.5:alpha=1,fade=out:st=$outro6:d=0.5:alpha=1[6a];\
[out][6a]overlay=x=0:y=0[out];\
[7]format=rgba,fade=in:st=$intro7:d=0.5:alpha=1,fade=out:st=$outro7:d=0.5:alpha=1[7a];\
[out][7a]overlay=x=0:y=0[out];\
[8]format=rgba,fade=in:st=$intro8:d=0.5:alpha=1,fade=out:st=$outro8:d=0.5:alpha=1[8a];\
[out][8a]overlay=x=0:y=0[out];\
[9]format=rgba,fade=in:st=$intro9:d=0.5:alpha=1,fade=out:st=$outro9:d=0.5:alpha=1[9a];\
[out][9a]overlay=x=0:y=0[out];\
[10]format=rgba,fade=in:st=$intro10:d=0.5:alpha=1,fade=out:st=$outro10:d=0.5:alpha=1[10a];\
[out][10a]overlay=x=0:y=0[out];\
[11]format=rgba,fade=in:st=$intro11:d=0.5:alpha=1,fade=out:st=$outro11:d=0.5:alpha=1[11a];\
[out][11a]overlay=x=0:y=0[out];\
[12]format=rgba,fade=in:st=$intro12:d=0.5:alpha=1,fade=out:st=$outro12:d=0.5:alpha=1[12a];\
[out][12a]overlay=x=0:y=0[out];\
[13]format=rgba,fade=in:st=$intro13:d=0.5:alpha=1,fade=out:st=$outro13:d=0.5:alpha=1[13a];\
[out][13a]overlay=x=0:y=0[out];\
[14]format=rgba,fade=in:st=$intro14:d=0.5:alpha=1,fade=out:st=$outro14:d=0.5:alpha=1[14a];\
[out][14a]overlay=x=0:y=0[out];\
[15]format=rgba,fade=in:st=$intro15:d=0.5:alpha=1,fade=out:st=$outro15:d=0.5:alpha=1[15a];\
[out][15a]overlay=x=0:y=0[out];\
[16]format=rgba,fade=in:st=$intro16:d=0.5:alpha=1,fade=out:st=$outro16:d=0.5:alpha=1[16a];\
[out][16a]overlay=x=0:y=0[out];\
[17]format=rgba,fade=in:st=$intro17:d=0.5:alpha=1,fade=out:st=$outro17:d=0.5:alpha=1[17a];\
[out][17a]overlay=x=0:y=0[out];\
[18]format=rgba,fade=in:st=$intro18:d=0.5:alpha=1,fade=out:st=$outro18:d=0.5:alpha=1[18a];\
[out][18a]overlay=x=0:y=0[out];\
[19]format=rgba,fade=in:st=$intro19:d=0.5:alpha=1,fade=out:st=$outro19:d=0.5:alpha=1[19a];\
[out][19a]overlay=x=0:y=0[out];\
[20]format=rgba,fade=in:st=$intro20:d=0.5:alpha=1,fade=out:st=$outro20:d=0.5:alpha=1[20a];\
[out][20a]overlay=x=0:y=0[out];\
[21]format=rgba,fade=in:st=$intro21:d=0.5:alpha=1,fade=out:st=$outro21:d=0.5:alpha=1[21a];\
[out][21a]overlay=x=0:y=0[out];\
[22]format=rgba,fade=in:st=$intro22:d=0.5:alpha=1,fade=out:st=$outro22:d=0.5:alpha=1[22a];\
[out][22a]overlay=x=0:y=0[out];\
[23]format=rgba,fade=in:st=$intro23:d=0.5:alpha=1,fade=out:st=$outro23:d=0.5:alpha=1[23a];\
[out][23a]overlay=x=0:y=0[out];\
[24]format=rgba,fade=in:st=$intro24:d=0.5:alpha=1,fade=out:st=$outro24:d=0.5:alpha=1[24a];\
[out][24a]overlay=x=0:y=0[out];\
[25]format=rgba,fade=in:st=$intro25:d=0.5:alpha=1,fade=out:st=$outro25:d=0.5:alpha=1[25a];\
[out][25a]overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)[out];[out]drawtext=fontfile=/font.ttf:text='Text':fontcolor=white:fontsize=50:box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1810,\
drawtext=fontfile=/font.ttf:text='\:':fontcolor=red:fontsize=50:box=1:boxcolor=black@0:boxborderw=5:x=762:y=1813:enable='lt(mod(t,1),.5)',\
drawtext=fontfile=/font.ttf:fontsize=50:fontcolor=white:text='Elapsed Time  %{pts\:gmtime\:0\:%M\\\\\:%S} / $minutes\:$seconds':box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1860,
drawtext=fontfile=/font.ttf:fontsize=50:fontcolor=red:text='\:':box=1:boxcolor=black@.4:boxborderw=9:x=823:y=1865:enable='lt(mod(t,1),.4)',
drawtext=fontfile=/font.ttf:text='Text':y=1712:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=white:fontsize=85:enable='between(t,0,$((duration-1)))',\
drawtext=fontfile=/font.ttf:text='Text':y=1711:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=red:fontsize=85:enable='between(t,0,$((duration-1)))'[out]"\
 -map "[out]" -map 26:a -c:v libx264 -crf 18  -acodec aac video.mp4

So I'm not sure if setting a color format would help or what I can do. I know it is 4k and will be slow but for most of the video all it really needs to do is display a static picture but it seem like because there is an alpha channel it slows it way doing even it the transparency for most of the frames is at 0%.
Thank you to anyone who can help me make this more efficient!
Thanks to the helpful links provided I ended up with this and it runs at over 20 fps and looks great. I wish I could get the cuda HW acceleration to work but I couldn't figure out the hwupload hwdoanload and told me the pixel formats were incompatable but I am very happy with this!
#!/bin/bash

full_path="/Videos"
a_path=$full_path"/"$1"/"$2".wav"
font="/font.ttf"
images=25

duration_function() {
    ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $a_path
    return 100
}

duration="$(duration_function "$a_path")" 
duration=${duration%.*}

minutes=$((duration / 60))
seconds=$((duration % 60))

seconds=$(printf "%02d" $seconds)
fade=$((duration / images))

intro1=1
intro2=$((intro1+fade))
intro3=$((intro2+fade))
intro4=$((intro3+fade))
intro5=$((intro4+fade))
intro6=$((intro5+fade))
intro7=$((intro6+fade))
intro8=$((intro7+fade))
intro9=$((intro8+fade))
intro10=$((intro9+fade))
intro11=$((intro10+fade))
intro12=$((intro11+fade))
intro13=$((intro12+fade))
intro14=$((intro13+fade))
intro15=$((intro14+fade))
intro16=$((intro15+fade))
intro17=$((intro16+fade))
intro18=$((intro17+fade))
intro19=$((intro18+fade))
intro20=$((intro19+fade))
intro21=$((intro20+fade))
intro22=$((intro21+fade))
intro23=$((intro22+fade))
intro24=$((intro23+fade))
intro25=$((intro24+fade))

ffmpeg -y -hide_banner -threads 6 -f lavfi -i color=c=black:s=3840x2160:r=25:d=$duration -loop 1 -i 1.png -loop 1 -i 2.png -loop 1 -i 3.png -loop 1 -i 4.png -loop 1 -i 5.png -loop 1 -i 6.png -loop 1 -i 7.png -loop 1 -i 8.png -loop 1 -i 9.png -loop 1 -i 10.png -loop 1 -i 11.png -loop 1 -i 12.png -loop 1 -i 13.png -loop 1 -i 14.png -loop 1 -i 15.png -loop 1 -i 16.png -loop 1 -i 17.png -loop 1 -i 18.png -loop 1 -i 19.png -loop 1 -i 20.png -loop 1 -i 21.png -loop 1 -i 22.png -loop 1 -i 23.png -loop 1 -i 24.png -loop 1 -i 25.png -i $a_path -filter_complex "\
[0:v][1]xfade=transition=fade:duration=2:offset=$intro1[out];\
[out][2]xfade=transition=fade:duration=2:offset=$intro2[out];\
[out][3]xfade=transition=fade:duration=2:offset=$intro3[out];\
[out][4]xfade=transition=fade:duration=2:offset=$intro4[out];\
[out][5]xfade=transition=fade:duration=2:offset=$intro5[out];\
[out][6]xfade=transition=fade:duration=2:offset=$intro6[out];\
[out][7]xfade=transition=fade:duration=2:offset=$intro7[out];\
[out][8]xfade=transition=fade:duration=2:offset=$intro8[out];\
[out][9]xfade=transition=fade:duration=2:offset=$intro9[out];\
[out][10]xfade=transition=fade:duration=2:offset=$intro10[out];\
[out][11]xfade=transition=fade:duration=2:offset=$intro11[out];\
[out][12]xfade=transition=fade:duration=2:offset=$intro12[out];\
[out][13]xfade=transition=fade:duration=2:offset=$intro13[out];\
[out][14]xfade=transition=fade:duration=2:offset=$intro14[out];\
[out][15]xfade=transition=fade:duration=2:offset=$intro15[out];\
[out][16]xfade=transition=fade:duration=2:offset=$intro16[out];\
[out][17]xfade=transition=fade:duration=2:offset=$intro17[out];\
[out][18]xfade=transition=fade:duration=2:offset=$intro18[out];\
[out][19]xfade=transition=fade:duration=2:offset=$intro19[out];\
[out][20]xfade=transition=fade:duration=2:offset=$intro20[out];\
[out][21]xfade=transition=fade:duration=2:offset=$intro21[out];\
[out][22]xfade=transition=fade:duration=2:offset=$intro22[out];\
[out][23]xfade=transition=fade:duration=2:offset=$intro23[out];\
[out][24]xfade=transition=fade:duration=2:offset=$intro24[out];\
[out][25]xfade=transition=fade:duration=2:offset=$intro25[out];\
[out]drawtext=fontfile=$font:text='Text':fontcolor=white:fontsize=50:box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1810,\
drawtext=fontfile=$font:text='\:':fontcolor=red:fontsize=50:box=1:x=762:y=1813:enable='lt(mod(t,1),.5)',\
drawtext=fontfile=$font:fontsize=50:fontcolor=white:text='Elapsed Time  %{pts\:gmtime\:0\:%M\\\\\:%S} / $minutes\:$seconds':box=1:boxcolor=black@.4:boxborderw=9:x=300:y=1860,
drawtext=fontfile=$font:fontsize=50:fontcolor=red:text='\:':x=823:y=1865:enable='lt(mod(t,1),.4)',
drawtext=fontfile=$font:text='Text':y=1712:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=white:fontsize=85:enable='between(t,0,$((duration-1)))',\
drawtext=fontfile=$font:text='Text':y=1711:x=(if(lt(10*n/(300+tw)\,1)\,mod(10*n\,300+tw)-tw\,300)):fontcolor=red:fontsize=85:enable='between(t,0,$((duration-1)))'[out]"\
 -map "[out]" -map 26:a -shortest -c:v hevc_nvenc -rc vbr -cq 24 -qmin 24 -qmax 24 -profile:v main10 -b:v 0K -c:a aac -map 0 video.mp4

**Tags:** ffmpeg, bash

> **Comments:**
> **username_1**: Try this. Determine the length of the audio and calculate the fade in-out length per image. Then generate 25 *individual* video files from each of the 25 images with the fade in-out effect. Then use the [ffmpeg concat demuxer](https://stackoverflow.com/questions/49371422/how-to-merge-two-videos-without-re-encoding) to merge all the 25 videos files into one video (this will join the videos together without re-encoding it). Finally [add the audio](https://superuser.com/a/590210) to the final video.  
> **username_1**: See also - [3 Methods you need to know about FFmpeg transition animation](https://donglumail.medium.com/3-methods-you-need-to-know-for-ffmpeg-transition-animation-7d2ea8f7ced7) and experiment which is the fastest.  
> **username_0**: Is it that ffmpeg has to calculate all the images even if only one of them is visible? I made a test with just two images thinking that was the case and even with only two images it was the same slow speed. Or would I have to make videos that were just the 1 second transitions and the 15 or so odd seconds where there was no transition would be a separate video file too. So I would need 50 videos. I could probably script that so it wouldn't be so bad. I'm not sure how to deal with the text. Some is scrolling and it takes the cues from the total length of the video & there is a elapsed counter.  
> **username_0**: Thank you for the links! They pointed me to xfade and now I am getting over 20 fps second the quality looks great!  

---

## 0 answers

