Trimming and joining media files using ffmpeg

0

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

EDIT:

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:a]atrim=duration=1500[aa];\
 [0:v]trim=start=1980,setpts=PTS-STARTPTS[bv]; \
 [0:a]atrim=start=1980,asetpts=PTS-STARTPTS[ba];\
 [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.

Anmol Singh Jaggi

Posted 2016-04-11T17:56:29.280

Reputation: 211

In the seek method, why the duration indicator -t in the 2nd command? – Gyan – 2016-04-11T18:38:55.857

@Mulvya It specifies the duration of the clipping. Now that you've mentioned it, I see that I've made a small mistake: instead of -t 00:53:50 in the second command, it should have been -t 00:21:20. – Anmol Singh Jaggi – 2016-04-11T18:43:33.693

@Mulvya Even after correcting that, I'm getting the same error. Alos, I've corrected this is the question. – Anmol Singh Jaggi – 2016-04-11T18:45:53.847

trim does not work with HH:MM:SS currently. Specify in seconds. And what I meant was since you want the file till the end except for a portion in the middle, there's no need to specify t in the second command. If you still get the error, copy the whole file to a new container and try again: ffmpeg -i input -c copy new.mp4 – Gyan – 2016-04-11T19:15:50.253

Okay, I got what you're trying to say. I've edited the question accordingly. – Anmol Singh Jaggi – 2016-04-11T19:36:44.103

@Mulvya I tried the same thing after copying to a new container but I'm getting the same error. – Anmol Singh Jaggi – 2016-04-11T19:40:21.043

Some other potential useful information: The segment I'm trying to remove looks corrupted; the video seems stuck at the same frame as time increases. – Anmol Singh Jaggi – 2016-04-11T19:49:11.110

@Mulvya Check the edits to the question. Do you have any idea regarding the second method? – Anmol Singh Jaggi – 2016-04-11T20:59:59.233

Also, I have another question: Do any of these mehtods result in a reduction of the output video quality? – Anmol Singh Jaggi – 2016-04-11T21:50:25.873

Answers

3

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

Gyan

Posted 2016-04-11T17:56:29.280

Reputation: 21 016

Thanks for the tip regarding quality. As for the second method, it still isn't working. The output file doesn't contain the second video at all. It's size is almost similar to the first video. Here is the log.

– Anmol Singh Jaggi – 2016-04-12T08:22:09.267

Sorry, the concat list has to refer to the whole input file. – Gyan – 2016-04-12T08:29:18.230

Okay, I tried that too, but I'm getting the same input.txt: Invalid argument error, with the second video file missing from the output file. – Anmol Singh Jaggi – 2016-04-12T09:27:53.440