10

How can I cut a video into multiple parts and then join them together to make a new video with ffmpeg?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
rinofcan
  • 323
  • 1
  • 3
  • 9

3 Answers3

15

You can use the concat demuxer.

#1 Create a text file

file video.mp4
inpoint 34.5
outpoint 55.1
file video.mp4
inpoint 111.0
outpoint 155.3
file video.mp4
inpoint 278
outpoint 316.4

The inpoint/outpoint directives specify the trim in and out points in seconds for the file listed above them.

#2a Create the joint file

ffmpeg -f concat -i list.txt combined.mp4

#2b Do the overlay together

ffmpeg -f concat -i list.txt -i background.mp4 -filter_complex "[0:v]scale=400:400[v1];[1:v][v1]overlay=0:0:shortest=1" -shortest -preset superfast "output.mp4"

External Audio stream with concat

ffmpeg -i 12m.mp4 -f concat -i list.txt -vf setpts=(PTS-STARTPTS)/1.1 -af atempo=1.1 -map 1:v -map 0:a -shortest new.mp4
Gyan
  • 85,394
  • 9
  • 169
  • 201
  • after run commands *** ffmpeg -f concat -i list.txt combined.mp4 *** then i want to run commands *** ffmpeg -i combined.mp4 -i background.mp4 -filter_complex "[0:v] scale=400:400 [v1], [1:v][v1]overlay=0:0" -shortest -preset superfast "output.mp4" *** || Let two lines of code run in a .bat directory What should I do to connect those two lines together? thank for help – rinofcan Mar 14 '17 at 05:28
  • When i run command #2b : errror command: option loop not found. After run commands *** ffmpeg -f concat -i list.txt combined.mp4 *** then i want to run commands *** ffmpeg -i 12m.mp4 -i combined.mp4 -vf setpts=(PTS-STARTPTS)/1.1 -af atempo=1.1 -map 1:v -map 0:a -shortest new.mp4 *** || Let two lines of code run in a .bat directory What should I do to connect those two lines together? – rinofcan Mar 14 '17 at 06:32
  • Corrected cmd and added new one. – Gyan Mar 14 '17 at 06:45
  • hello Mulvya when i creat list.txt if each video in other folder ( ex: D:\video1 and D:\video2) What should I do? example text list: file D:\video1\videoa inpoint 34.5 outpoint 55.1 file D:\video1\videob inpoint 278 outpoint 316.4 – rinofcan Apr 11 '17 at 15:15
  • Add `-safe 0` before `-i` on the cmd line. – Gyan Apr 11 '17 at 16:18
  • i have 10 video in folder , I want to livestream on youtube loop that 10 video (24/7) Can you help me? – rinofcan Apr 14 '17 at 16:03
  • I don't understand your answer. What is #2b for? I tried #2a to splice together parts of an .flv file, and it works... but the video quality noticeable degrades. Is there a better way? Probably recoding is necessary? – Stefan Reich Jan 17 '19 at 14:07
  • @StefanReich see comment above by OP at `Mar 14 '17 at 5:28`. If you're saving to FLV, add `-c:v libx264`. If that encoder is already chosen, add `-crf 18`. – Gyan Jan 17 '19 at 14:24
  • @Gyan I am using the above method but with a single video file and just using multiple inpoints and outpoints. I need both audio and video and I am finding the audio is off. Is there something I can do? – CRAIG Mar 23 '20 at 02:44
6

You question is quiet general...
The following example may help you, but it might not solve your specific issues.

The example applies three stages:

  • Create synthetic video (with no audio):

    ffmpeg -f lavfi -i testsrc=duration=3:size=160x120:rate=10 -c:v rawvideo -pix_fmt rgb24 testsrc.avi
    

    (The created video is uncompressed).
    Reference: https://trac.ffmpeg.org/wiki/FilteringGuide

  • Cut video into 3 parts (creating 3 video files):

    ffmpeg -i testsrc.avi -ss 00:00:00 -c copy -t 00:00:01 sec0.avi
    ffmpeg -i testsrc.avi -ss 00:00:01 -c copy -t 00:00:01 sec1.avi
    ffmpeg -i testsrc.avi -ss 00:00:02 -c copy -t 00:00:01 sec2.avi
    

    Reference: https://superuser.com/questions/138331/using-ffmpeg-to-cut-up-video

  • Concatenate (merge) 3 parts in reverse order:

    ffmpeg -i "concat:sec2.avi|sec1.avi|sec0.avi" -codec copy output.avi
    

    Note: for Linux use single quotes '
    Reference: Concatenate two mp4 files using ffmpeg

Synthetic video looks as the following image:
enter image description here

Community
  • 1
  • 1
Rotem
  • 30,366
  • 4
  • 32
  • 65
4

For anyone coming into this, I noticed that Gyan's answer has the drawback that inpoints and outpoints are approximate in the case of inter-frame codecs (see the doc).

The following command (from Ilogan's answer) does not have this drawback. It works both for one or multiple inputs.

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 \ 
-filter_complex \
"[0:v]trim=3.48:5.72,setpts=PTS-STARTPTS[v0]; \
 [0:v]trim=6.56:8.68,setpts=PTS-STARTPTS[v0b]; \
 [1:v]trim=13.52:15.36,setpts=PTS-STARTPTS[v1]; \
 [1:v]trim=17.56:23.32,setpts=PTS-STARTPTS[v1b]; \
 [2:v]trim=20.6:23.96,setpts=PTS-STARTPTS[v2]; \
 [v0][v0b][v1][v1b][v2]concat=n=5:v=1:a=0[v]" \
-map "[v]" -an -crf 17 output.mp4
  • 1
    The drawback of your solution is that the video needs to be re-encoded which may be okay for some uses cases. – Garuuk Feb 18 '23 at 19:38