如何用FFmpeg按多帧裁剪视频并拼接?能否通过帧数与FPS换算时间?
Alright, let's cover both your questions—how to trim video using exact frame numbers and concatenate clips, plus whether converting frames to time via FPS is a valid approach.
Direct Frame-Based Trimming (Most Precise)
You don’t need to convert frames to time to trim video—FFmpeg’s trim filter supports start_frame and end_frame parameters for video streams, which avoids any rounding errors that can come from FPS conversion. Since audio doesn’t use frame numbers directly, we’ll calculate matching time points by dividing frame numbers by your FPS (20 in this case).
Here’s the command tailored to your frame values:
ffmpeg -i input.mp4 -filter_complex \ "[0:v]trim=start_frame=100:end_frame=200,setpts=PTS-STARTPTS[v0]; \ [0:a]atrim=start=100/20:end=200/20,asetpts=PTS-STARTPTS[a0]; \ [0:v]trim=start_frame=450:end_frame=700,setpts=PTS-STARTPTS[v1]; \ [0:a]atrim=start=450/20:end=700/20,asetpts=PTS-STARTPTS[a1]; \ [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \ -map "[out]" output.mp4
- Video Notes:
end_frameis exclusive—soend_frame=200will include up to frame 199. If you want frames 100 to 200 inclusive, adjust it toend_frame=201(this depends on whether you count frames starting at 0 or 1; double-check your source if unsure). - Audio Sync: The
atrimfilter uses time values, soframe_number / fpsgives us the exact start/end times to match the video clips perfectly.
Converting Frames to Time (Valid Alternative)
Yes, converting frames to time using time = frame_number / fps is completely valid and works as expected. This is the approach you outlined in your sample code, and it’s great if you prefer pre-calculating time values first.
Using your parameters:
time_x_1 = 100/20 = 5secondstime_x_2 = 200/20 = 10secondstime_y_1 = 450/20 = 22.5secondstime_y_2 = 700/20 = 35seconds
Here’s the simplified command with pre-calculated times:
ffmpeg -i input.mp4 -filter_complex \ "[0:v]trim=5:10,setpts=PTS-STARTPTS[v0]; \ [0:a]atrim=5:10,asetpts=PTS-STARTPTS[a0]; \ [0:v]trim=22.5:35,setpts=PTS-STARTPTS[v1]; \ [0:a]atrim=22.5:35,asetpts=PTS-STARTPTS[a1]; \ [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \ -map "[out]" output.mp4
Just make sure your specified FPS matches the input video’s actual FPS (verify with ffmpeg -i input.mp4 if you’re unsure). If the video uses variable frame rate (VFR), the frame-based trimming method is safer for perfect sync, but fixed frame rate (CFR) videos will work flawlessly with either approach.
内容的提问来源于stack exchange,提问作者puneet18




