How to concat multiple explicit image paths to video with ffmpeg - python

I am trying to figure out how to create a video from explicit paths to an image sequence.
I am writing these images from Houdini.
Instead of doing some kind of regex matching to replace $F3 with %03d I am trying to figure out how to concat the image paths into a video.
I'm trying to do something like this:
ffmpeg -y -framerate 12 -i -start_number 1 -i test_00001.jpg -start_number 2 -i test_00002.jpg -start_number 3 -i test_00003.jpg -start_number 4 -i test_00004.jpg -start_number 5 -i test_00005.jpg -start_number 6 -i test_00006.jpg -start_number 7 -i test_00007.jpg -start_number 8 -i test_00008.jpg -start_number 9 -i test_00009.jpg -filter_complex "concat=n=3" -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p $HOME/Desktop/test.mp4
This result only plays a couple of frames in the result video
If I write the images to a text file with the following format
file '/Volumes/hqueue/projects/Fire/render/test_1.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_2.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_3.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_4.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_5.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_6.jpg'
file '/Volumes/hqueue/projects/Fire/render/test_7.jpg
and then run a command like the following
ffmpeg -y -framerate 12 -f concat -i /var/folders/fy/8zlxyq497kz0nzgb1nqc9xf59rwbjm/T/image_list.txt -c:v libx264 -profile:v high -c copy -crf 20 -pix_fmt yuv420p $HOME/Desktop/test.mp4
I get the following output
[concat # 0x7f870e809c00] Unsafe file name '/Volumes/hqueue/projects/Fire/render/test_1.jpg'
/var/folders/fy/8zlxyq497kz0nzgb1nqc9xf59rwbjm/T/image_list.txt: Operation not permitted
Right now it's producing a video, but only with a couple of the input frames.

I put selected files in one folder and use
ffmpeg -pattern_type glob -i '*.jpg' output.mp4

Related

ffmpeg multiple input video in grid and simultaneous audio

i would like to copy a video into n videos in one grid:
best example: https://www.youtube.com/watch?v=lYKDTLGH-TQ&ab_channel=TheRabbit_123
This is my code, its working, but problem is, the audio seems to be like its played by one version.. I want the "echo" thats created by a lot of files like on the video above.
def create_4_in_one(number):
shutil.copy("start.mp4", f"video.mp4")
for i in range(number):
shutil.copy("video.mp4", f"temp_videa/{i}.mp4")
subprocess.call(f'ffmpeg -y -i video.mp4 -vf "scale=iw/2:ih/2" -c:a copy video_half.mp4',
shell=True)
subprocess.call(f'ffmpeg -y -i video_half.mp4 -i video_half.mp4 -i video_half.mp4 -i video_half.mp4 -filter_complex "[0:v][1:v]hstack[t];[2:v][3:v]hstack[b];[t][b]vstack[v]; [0:a][1:a][2:a][3:a]amerge=inputs=4[a]" -map "[v]" -map "[a]" -map 0:a -map 1:a -map 2:a -map 3:a -c:a aac -b:a 128k -ac 2 -shortest output.mp4',
shell=True)
os.remove("video.mp4")
os.remove("video_half.mp4")
os.rename('output.mp4', 'video.mp4')
os.remove("video.mp4")
Thanks in advance.

Ffmpeg alpha channel video generation

I am trying to remove a background from a video using ffmpeg and a PY library that does that, the PY lib (backgroundremover) just creates a matte.mp4 file as an output, having the background as black and the person as white silhouette.
PY lib: https://github.com/nadermx/backgroundremover#advance-usage-for-video
What I am doing at the moment:
Shrink & convert the video to MP4
ffmpeg -i ios.mov -s 320x240 -filter:v fps=30 -vf scale=320:-2 edited.mp4
Create the matte video
backgroundremover -i edited.mp4 -wn 4 -mk -o matte.mp4
Create video with alpha channel (the problem)
ffmpeg -i edited.mp4 -i matte.mp4 -filter_complex "[0:v][1:v]alphamerge" -shortest -c:v qtrle -an output.mov
Last command fails with invalid frame sizes, how do I force a frame size or skip this check?
Error:
[swscaler # 0x7ff5c957b000] No accelerated colorspace conversion found from yuv420p to argb.
[Parsed_alphamerge_0 # 0x7ff5c4e6d480] Input frame sizes do not match (320x240 vs 426x320).
[Parsed_alphamerge_0 # 0x7ff5c4e6d480] Failed to configure output pad on Parsed_alphamerge_0
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Answer:
ffmpeg -y -i edited.mp4 -i matte.mp4 -f lavfi -i color=c=black:s=320x240 -filter_complex "[1:v]scale=320:240,setsar=1:1,split[vs][alpha];[0:v][vs]alphamerge[vt];[2:v][vt]overlay=shortest=1[rgb];[rgb][alpha]alphamerge" -shortest -c:v hevc_videotoolbox -allow_sw 1 -alpha_quality 0.75 -vtag hvc1 -pix_fmt yuva420p -an output.mov
The error Input frame sizes do not match (320x240 vs 426x320) is "self explained".
The resolution of edited.mp4 is 320x240.
The resolution of matte.mp4 is 426x320.
I don't know why backgroundremover modifies the resolution from 320x240 to 426x320.
The rest of the messages are just warnings.
I am not sure about it, but I think the first FFmpeg command should be:
ffmpeg -y -i ios.mov -filter:v fps=30 -vf scale=320:240,setsar=1:1 edited.mp4
It's not solving the issue - the resolution of matte.mp4 is still 426x320.
It could be a bug in backgroundremover...
You may solve the error message using scale filer.
The alpha merge should be followed by an overlay filter:
ffmpeg -y -i edited.mp4 -i matte.mp4 -f lavfi -i color=c=black:s=320x240 -filter_complex "[1:v]scale=320:240,setsar=1:1[vs];[0:v][vs]alphamerge[vt];[2:v][vt]overlay=shortest=1" -shortest -c:v qtrle -an output.mov
Sample output:

Set images duration in FFmpeg when converting a list of images to one video?

I achieved my need by converting a list of images within a folder to one video using this cmd
ffmpeg -framerate 1 -loop 1 -pattern_type glob -i '*.jpg' -pix_fmt yuv420p -t 12 video.mp4;
I just need to set a duration for example 6s for each image! Is this possible using FFmpeg?
If you want to play each frame for 6 seconds use -framerate 1/6. Also, -loop 1 is not required unless you want the files to all finish encoding once and then start over at the beginning.
ffmpeg -framerate 1/6 -pattern_type glob -i "*.jpg" -vcodec libx264 \
-pix_fmt yuv420p -r 30 -threads 4 -crf 25 -refs 1 -bf 0 -coder 0 -g 25 \
-keyint_min 15 -movflags +faststart output.mp4
You can change -crf etc to your requirements.

How to combine multiple audios and videos into a single file?

I have a bunch of audio and video files and their corresponding start time in a stream.
Like this diagram below:
How can I combine this all into a single video file efficiently?
I've tried ffmpeg but it was too slow (I don't know if I used ffmpeg correctly or not)
This is my ffmpeg command example:
ffmpeg -i audio_0_3.mp3 -i audio_1_4.mp3 -i audio_2_5.mp3 -i audio_2_6.mp3 -i audio_2_7.mp3 -i audio_3_10.mp3 -i audio_3_8.mp3 -i audio_3_9.mp3 \
-filter_complex [0:a]adelay=0ms[s0];[1:a]adelay=36282ms[s1];[2:a]adelay=462385ms[s2];[3:a]adelay=686909ms[s3];[4:a]adelay=876931ms[s4];[5:a]adelay=1675187ms[s5];[6:a]adelay=1339944ms[s6];[7:a]adelay=1567946ms[s7];[s0][s1][s2][s3][s4][s5][s6][s7]amix=inputs=8[s8] \
-map [s8] out.mp4

Joining audio file and all frame picture to video format with Python ffmpeg

i have a tmp directory which contains a collection of image frames and audio files. i am using linux mint 19.3 and python3.8. in the terminal I type
ffmpeg -i tmp/%d.png -vcodec png tmp/output.mov -y
and ffmpeg -i tmp/output.mov -i tmp/audio.mp3 -codec copy output.mov -y
then the collection of images and audio in the directory will become a complete video. that I asked
when I run it in python using the syntax
call(["ffmpeg", "-i", "tmp/%d.png" , "-vcodec", "png", "tmp/output.mov", "-y"],stdout=open(os.devnull, "w"), stderr=STDOUT)
and
call(["ffmpeg", "-i", "tmp/output.mov", "-i", "tmp/audio.mp3", "-codec", "copy", "output.mov", "-y"],stdout=open(os.devnull, "w"), stderr=STDOUT)
it does not merge into a video (without output error)
I tried the syntax
os.system("ffmpeg -i tmp/%d.png -vcodec png tmp/output.mov -y")
and
os.system("ffmpeg -i tmp/output.mov -i tmp/audio.mp3 -codec copy output.mov -y"), the video failed to merge with the error output tmp/output.mov: No such file or directory
Please help. thank you
Use the full path
Instead of tmp/output.mov use /tmp/output.mov. Do this for the rest of the inputs and outputs.
Do everything in one command
ffmpeg -y -i /tmp/%d.png -i /tmp/audio.mp3 -codec copy -shortest output.mov

Categories