Using Ubuntu 18.04 I have some screencast video files in mp4 container (h.264/mp3 codecs) that I want at times merge (i.e. C.mp4 = A.mp4+B.mp4) or at times cut removing some intervals (e.g. D.mp4 = A.mp4[0,320{seconds}]+A.mp4[325,340]+C.mp4).
I am now using kdenlive, it woks but it re-encode everything and it seems a bit too much for such a task.
Is there a simpler way to do that without re-encoding (even, and perhaps preferred, command line or stable Python/Julia/R/.. way) ?
I am thinking at something like PDFtk for the pdfs :-))
PS: I did try ffmpeg -ss 00:00:05 -to 00:00:10 -i test1.mp4 test2.mp4 but I have an error:
Option to (record or transcode stop time) cannot be applied to input url test1.mp4 -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
My files have the same container, codec and resolution.
(I know nothing of video stuff..)
EDIT: I don't want to look pessimistic, but more I look on it more I behave that what I thought to be super simple is indeed super complicate. What a pity nobody wrote a high-level interface to perform something like that.. I'm sure I am not the first one with such a need..
EDIT2: I found moviepy, but it is still far from my original idea (it re-encodes and it has longer than needed API.. I can script it but the reencoding problem remains):
pip install moviepy
from moviepy.editor import VideoFileClip, concatenate_videoclips
c1 = VideoFileClip("test1.mp4").subclip(0,5)
c2 = VideoFileClip("test1.mp4").subclip(10,15)
f = concatenate_videoclips([c1,c2])
f.write_videofile(test2.mp4) 2 Answers
You can do it with ffmpeg. You need to order the options properly and add two more:
ffmpeg -i INFILE.mp4 -vcodec copy -acodec copy -ss 00:01:00.000 -t 00:00:10.000 OUTFILE.mp4From here.
1Well, as posted in my own question this doesn't solve the problem of the re-encoding, but at least it is a handy interface. Just use it with
vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>#!/usr/bin/python3
import sys, getopt, re
def printerror(errormsg): print("*** vcat - concatenate video segments using moviepy ***\n") print("ERROR:", errormsg,"\n") print("Usage: vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>") print("Optional start and end points should be given in seconds. If files have spaces should be quoted (e.g. \"input file.mp4[5-30]\").")
try: from moviepy.editor import VideoFileClip, concatenate_videoclips
except ImportError: printerror("You don't seem to have moviepy installed. Install it with `pip install moviepy`.") exit(1)
def main(argv): inputfiles_arg = '' outputfile = '' try: opts, args = getopt.getopt(argv,"hi:o:",["input=","output="]) except getopt.GetoptError as err: printerror(str(err)) sys.exit(2) for opt, arg in opts: if opt == '-h': printerror("") sys.exit() elif opt in ("-i", "--input"): inputfiles_arg = arg elif opt in ("-o", "--output"): outputfile = arg if outputfile =='': printerror("Output file not specified") iFiles = inputfiles_arg.split(',') clips=[] for iFile in iFiles: subclip = re.search(r"\[([0-9\-\.]+)\]", iFile) if subclip is None: clips.append(VideoFileClip(iFile)) else: dims = subclip.group(1).split('-') if len(dims) != 2: printerror("If a specific segment of a file is specified, this should be given as [startseconds-endseconds]") iFile = iFile.replace("["+subclip.group(1)+"]",'') clips.append(VideoFileClip(iFile).subclip(float(dims[0]),float(dims[1]))) f = concatenate_videoclips(clips) f.write_videofile(outputfile)
if __name__ == "__main__": main(sys.argv[1:])Disclaimer: I don't use Python by a while, so sure there could be better approaches.. bdw it's really nice to be able to do what you want to do in a few hours because of the enormous documentation you can find on the net about python..