H.264, which is what libx264
encodes to, does not support transparency. Neither does mpeg4
, the default codec for AVI. MOV output defaults to libx264
as well.
You can do this in one command:
ffmpeg -i original.mp4 -framerate 60 -pattern_type glob -i images/*.png \
-filter_complex "[0:v]scale=1920x960,setdar=16:9[base];[1:v]scale=1920x960,setdar=16:9[ovr];\
[ovr][base]blend=all_mode='overlay':all_opacity=0.7[v]"
-map [v] result.mp4
You don't need to scale both videos.If you just want the PNGs to scale the same as the base video, you can use scale2ref
:
ffmpeg -i original.mp4 -framerate 60 -pattern_type glob -i images/*.png \
-filter_complex "[1:v][0:v]scale2ref=iw:ih[ovr][base]; \
[ovr][base]blend=all_mode='overlay':all_opacity=0.7[v]"
-map [v] result.mp4
Now, you have specified a custom DAR (1920x960
is not 16:9
). If that needs to be set, use
[1:v][0:v]scale2ref=iw:ih,setdar=16:9[ovr][base];
This uses a different method to apply the overlay.
ffmpeg -i original.mp4 -framerate 60 -pattern_type glob -i "images/*.png" \
-filter_complex "[1:v][0:v]scale2ref=iw:ih[ovr][base]; \
[ovr]colorchannelmixer=aa=0.7[ovrl]; [base][ovrl]overlay[v]"
-map [v] result.mp4
This is indeed due to the H264 PTS generation bug. My suggestion in the comment works for me. But so does the method at the end of the post.
Command for initial file:
ffmpeg -framerate 5 -start_number 1 -t 1 -i "f%d.png" -c:v libx264 -pix_fmt yuv420p -r 5 -bf 0 initial.mp4
Command for individual frames:
ffmpeg -framerate 5 -i "f6.png" -c:v libx264 -pix_fmt yuv420p -bf 0 -r 5 next1.mp4
...
ffmpeg -framerate 5 -i "f10.png" -c:v libx264 -pix_fmt yuv420p -bf 0 -r 5 next5.mp4
A single join:
list.txt:
file initial.mp4
file next1.mp4
and
ffmpeg -f concat -i list.txt -auto_convert 1 -c copy with6.mp4
with6.mp4:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'with6.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.2.100
Duration: 00:00:01.20, start: 0.000000, bitrate: 129 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 124 kb/s, 5 fps, 5 tbr, 10240 tbn, 10 tbc (default)
Metadata:
handler_name : VideoHandler
Join the rest at once:
file with6.mp4
file next2.mp4
file next3.mp4
file next4.mp4
file next5.mp4
and
ffmpeg -f concat -i list.txt -auto_convert 1 -c copy with6.mp4
with10.mp4:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'with10.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.2.100
Duration: 00:00:02.00, start: 0.000000, bitrate: 168 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 165 kb/s, 5 fps, 5 tbr, 10240 tbn, 10 tbc (default)
Metadata:
handler_name : VideoHandler
The other method is to keep your commands as-is but mux to MKV first, and then remux to MP4 i.e.
ffmpeg -f concat -i concat.txt -c copy new_output.mkv
ffmpeg -i new_output.mkv -c copy new_output.mp4
Best Answer
You can use the concat demuxer.
First, prepare a text file containing the list of all images in the order you want. In Windows, from a command prompt, you can run this command, in the folder:
dir *.jpg /b /on > list.txt
Now prefix each line with
file '
and suffix with'
, so that each line looks likefile 'ADAM SANDLER.jpg'
you may want to duplicate the last line due to a bug in the fps filter.
Now, if all your images are of the same size, run
If not, and assuming
1920x1080
as output video size, runThe
-r 1/2
is the input framerate and determines how long each images remains, in this case, 2 seconds. I've set the output framerate at8
because some players may fail to play the output. CRF controls the quality. Lower values produce better result but larger files.For the edited Q:
Use