使用FFmpeg剪辑视频时遇-to值小于-ss错误的解决求助
-to value smaller than -ss Error When Trimming by Frame Numbers Let's break down why you're hitting this error and fix it step by step:
The Root Cause
FFmpeg's time format hh:mm:ss.xxx doesn't treat the decimal part as a frame number—it's a fraction of a second. When you pass 0:0:47.21, FFmpeg reads that as 47.21 seconds, not 47 seconds and 21 frames. Since your start time is 0:0:47.4 (47.4 seconds), 47.21 is indeed earlier than 47.4, hence the "value smaller than -ss" error.
For a 25fps video, each frame is 1/25 = 0.04 seconds. So 47 seconds and 21 frames translates to 47 + 21/25 = 47.84 seconds—not 47.21. That's the key mistake here.
Solution 1: Convert Frames to Proper Time Values
First, calculate the actual time in seconds for your start/end points, then format it correctly for FFmpeg:
- Total seconds =
(hours * 3600) + (minutes * 60) + seconds + (frames / fps) - For your example:
- Start: 0h0m47s4f →
47 + 4/25 = 47.16seconds → format as00:00:47.16 - End: 0h0m47s21f →
47 + 21/25 = 47.84seconds → format as00:00:47.84
- Start: 0h0m47s4f →
Solution 2: Update Your Python Code to Automate the Conversion
Replace your manual string concatenation with code that calculates the correct time values. Here's the revised version:
import os fps = 25 # Match your video's frame rate inputvideo = "your_input_file" outputvideo = "your_output_file" # Example values: fhours=0, fminutes=0, fseconds=47, fframes=4 # lhours=0, lminutes=0, lseconds=47, lframes=21 # Calculate total seconds for start and end times start_total = fhours * 3600 + fminutes * 60 + fseconds + fframes / fps end_total = lhours * 3600 + lminutes * 60 + lseconds + lframes / fps # Format into FFmpeg-compatible time string (hh:mm:ss.xx) def format_time(total_seconds): hours = int(total_seconds // 3600) minutes = int((total_seconds % 3600) // 60) seconds = total_seconds % 60 return f"{hours:02d}:{minutes:02d}:{seconds:.2f}" start_time = format_time(start_total) end_time = format_time(end_total) # Build and run the command command = f'ffmpeg -i {inputvideo}.mp4 -qscale:v 2 -vf scale=427:240 -ss "{start_time}" -to "{end_time}" {outputvideo}.avi' os.system(command)
Bonus: Frame-Exact Trimming with Filters
If you want to avoid time conversion entirely and work directly with frame numbers, use FFmpeg's select and setpts filters. This is more reliable for frame-precise cuts:
ffmpeg -i input.mp4 -qscale:v 2 -vf "scale=427:240,select='between(n,START_FRAME,END_FRAME)',setpts=N/FRAME_RATE/TB" output.avi
- Replace
START_FRAMEandEND_FRAMEwith the actual frame numbers (counting starts at 0). For your example:- Start frame:
0*3600*25 + 0*60*25 + 47*25 +4 = 1179 - End frame:
0*3600*25 +0*60*25 +47*25 +21=1196
- Start frame:
You can also integrate this into your Python code by calculating the frame numbers directly instead of time values.
内容的提问来源于stack exchange,提问作者dusa

