Trimming and joining media files using ffmpeg

.mp4ffmpegmediavideovideo editing

I am trying to remove a segment (00:26:00 – 00:32:30) from a video file input.mp4.
Since there is no way to do that directly using ffmpeg (as far as I know), I am instead cutting the segments which I want in the output and then concatenating them.

After searching a bit, I've found that there are 2 ways to do this:

Unfortunately, both these methods are failing for me.

I am going to explain the steps I performed in both the methods:

1. Using trim:

EDIT: This method works now; skip to the second method instead.

Command used:

ffmpeg -i input.mp4 -filter_complex \
"[0:v]trim=duration=00:26:00[a]; \
[0:v]trim=start=00:32:30,setpts=PTS-STARTPTS[b]; \
[a][b]concat[c]" -map [c] out.mp4

Command output: Link

The output file is less than 1 minutes long and is of just 6.8 MB, whereas the input file was 900 MB.

2. Using seek

Command used:

# Cut first wanted segment
ffmpeg -ss 00:00:00 -i input.mp4 -t 00:26:00 -c copy -avoid_negative_ts 1 first.mp4

# Cut second wanted segment
ffmpeg -ss 00:32:30 -i input.mp4 -c copy -avoid_negative_ts 1 second.mp4

# Combine all the wanted segments
ffmpeg -f concat -i input.txt -c copy output.mp4

where input.txt contains:

file first.mp4
file second.mp4

Command output: Link (The error is mentioned on line 90: input.txt: Invalid argument)

The output file I get in this case is only about 500 MB (input file being 900 MB), and contains first video + first few minutes of the second video.

My system details:

  • Ubuntu 14.04

  • ffmpeg version: Link


Method 1 using trim is now working, thanks to @Mulvya's comment regarding writing seconds as the unit of time instead of the HH:MM:SS notation as it is broken.

New command:

ffmpeg -i input.mp4 -filter_complex \
"[0:v]trim=duration=1500[av]; \
 [0:v]trim=start=1980,setpts=PTS-STARTPTS[bv]; \
 [av][bv]concat[outv]; [aa][ba]concat=v=0:a=1[outa]" \
 -map [outv] -map [outa] out.mp4

But, I still want to know what's wrong with the second method.

Best Answer

The trim filter does not work with HH:MM:SS currently. Specify in seconds. This method re-encodes the video, so there is a reduction in quality. You can specify a CRF value e.g. -crf 20 to control quality. Lower values produce better quality but larger files. 18 to 28 is a decent range to try.

As for the second method, try by specifying the cutpoints in the text file i.e.

file 'input.mp4'
duration 1560
file 'input.mp4'
inpoint 1980

and then run

ffmpeg -f concat -i input.txt -c copy -fflags +genpts -avoid_negative_ts make_zero output.mp4

The relevant options for the text file are as follows:

  • duration
  • inpoint
  • outpoint
Related Question