Python调用FFmpeg图片转视频:非序列文件名适配问题
Hey there! I totally get not wanting to rename all those timestamped images—let's fix this with two reliable approaches that work directly with your existing file names.
Approach 1: Use FFmpeg's Concat Demuxer (Recommended)
This method lets you feed FFmpeg a custom list of your images, so you don't have to rely on the sequential filename pattern (img%01d.png) that your original command uses.
Step 1: Generate a File List in Python
First, we'll create a text file that lists all your timestamped images in the correct chronological order. Add this code to your Python script:
import os # Get all .jpg files in your target directory image_files = [file for file in os.listdir(".") if file.endswith(".jpg")] # Sort files to maintain chronological order (your timestamp filenames work with lexicographical sort) image_files.sort() # Write sorted file paths to a text file with open("image_sequence.txt", "w") as seq_file: for img_path in image_files: # Quote paths to avoid issues with spaces or special characters seq_file.write(f"file '{os.path.abspath(img_path)}'\n")
Step 2: Run FFmpeg with the File List
Replace your original os.system command with this one, which uses the text file we just created:
os.system("ffmpeg -f concat -safe 0 -i image_sequence.txt -vcodec mpeg4 -y movie.mp4")
Key flag breakdown:
-f concat: Tells FFmpeg to use the concat demuxer, which reads input from a list of files.-safe 0: Allows FFmpeg to use absolute file paths (skip if relative paths work for you).-i image_sequence.txt: Points FFmpeg to our sorted list of images.
Approach 2: Directly Pass Sorted Files to FFmpeg (No Temp File)
If you prefer not to create a temporary text file, use Python's subprocess module to pipe the sorted file list directly to FFmpeg:
import os import subprocess image_files = [file for file in os.listdir(".") if file.endswith(".jpg")] image_files.sort() # Build FFmpeg command arguments ffmpeg_args = [ "ffmpeg", "-framerate", "1", # Match your original -r 1 frame rate "-f", "concat", "-safe", "0", "-i", "-", # Read input from stdin "-vcodec", "mpeg4", "-y", "movie.mp4" ] # Pipe the sorted file list to FFmpeg with subprocess.Popen(ffmpeg_args, stdin=subprocess.PIPE, text=True) as proc: for img_path in image_files: proc.stdin.write(f"file '{os.path.abspath(img_path)}'\n")
Why Your Original Command Failed
The -i img%01d.png syntax relies on FFmpeg's image sequence pattern matching, which only works for files named with sequential numbers (like img1.png, img2.png). Your timestamped filenames don't fit this numeric sequence, so FFmpeg can't auto-detect them—hence the need for the concat demuxer approach.
Just double-check that your sort() call works for your timestamp format (since HH.MM.SS.MSS filenames sort lexicographically in chronological order, it should be perfect) and you'll get a video with the correct frame sequence.
内容的提问来源于stack exchange,提问作者DutchNinja

