如何获取使用FFmpeg修改帧率时被丢弃的帧编号
Absolutely, you can track which frames get dropped when converting your 30fps video to 20fps with ffmpeg! Here's a practical, step-by-step approach to capture those frame numbers:
Step 1: Extract Frame Info from the Original Video
First, we'll log every frame's details (including its number) from your source video using the showinfo filter. Run this command:
ffmpeg -i lamp02_20210212_060804-compressed.mp4 -vf "showinfo" -f null - 2> original_frames.log
- The
showinfofilter outputs metadata for each frame, including the frame number (labeledn:). - We redirect the stderr output (where ffmpeg sends filter logs) to
original_frames.logso we can parse it later.
Step 2: Extract Frame Info from the Resized Video
Next, do the same for the 20fps video you created (xx.mp4):
ffmpeg -i xx.mp4 -vf "showinfo" -f null - 2> retained_frames.log
This log will contain only the frames that were kept during the frame rate conversion.
Step 3: Compare Logs to Find Dropped Frames
Now we need to compare the two logs to find which frame numbers exist in the original but not in the resized video. You can use either a Python script or bash commands for this.
Option A: Python Script (Easy to Customize)
Create a script like this (save it as find_dropped_frames.py):
# Parse original video frame numbers original_frames = set() with open('original_frames.log', 'r') as log_file: for line in log_file: if 'n:' in line: # Extract the frame number from the line (e.g., "n:123" → 123) frame_num = int(line.split('n:')[1].split()[0]) original_frames.add(frame_num) # Parse retained video frame numbers retained_frames = set() with open('retained_frames.log', 'r') as log_file: for line in log_file: if 'n:' in line: frame_num = int(line.split('n:')[1].split()[0]) retained_frames.add(frame_num) # Calculate dropped frames and sort them dropped_frames = sorted(original_frames - retained_frames) # Print and save results print("Dropped frame numbers (0-indexed):") for num in dropped_frames: print(num) with open('dropped_frames.txt', 'w') as output_file: for num in dropped_frames: output_file.write(f"{num}\n")
Run it with:
python find_dropped_frames.py
This will print the dropped frame numbers and save them to dropped_frames.txt. Note: FFmpeg's showinfo uses 0-indexed frame numbers by default—if you prefer 1-indexed, just add +1 when extracting frame_num.
Option B: Bash Commands (No Scripting Needed)
If you prefer using terminal commands, run these:
# Extract and sort original frame numbers grep -o 'n:[0-9]*' original_frames.log | cut -d: -f2 | sort > original_frames.txt # Extract and sort retained frame numbers grep -o 'n:[0-9]*' retained_frames.log | cut -d: -f2 | sort > retained_frames.txt # Compare to find dropped frames (comm -23 shows lines only in the first file) comm -23 original_frames.txt retained_frames.txt > dropped_frames.txt # View the result cat dropped_frames.txt
Key Notes
- FFmpeg's
fpsfilter doesn't just drop frames at fixed intervals—it selects frames based on timestamp alignment to the target frame rate. This means the dropped frames might not follow a simple pattern, so comparing actual logged frames is the most accurate way to get the list. - If you want to avoid reprocessing the video twice, you can combine the frame rate conversion and retained frame logging into one command:
This way, you generate the resized video and its frame log in a single pass.ffmpeg -i lamp02_20210212_060804-compressed.mp4 -vf "fps=20,showinfo" xx.mp4 2> retained_frames.log
内容的提问来源于stack exchange,提问作者user42

