In this page, Albert Armea share a code to split videos by chapter using ffmpeg
. The code is straight forward, but not quite good-looking.
ffmpeg -i "$SOURCE.$EXT" 2>&1 | grep Chapter | sed -E "s/ *Chapter #([0-9]+\.[0-9]+): start ([0-9]+\.[0-9]+), end ([0-9]+\.[0-9]+)/-i \"$SOURCE.$EXT\" -vcodec copy -acodec copy -ss \2 -to \3 \"$SOURCE-\1.$EXT\"/" | xargs -n 11 ffmpeg
Is there an elegant way to do this job?
Split MP4 Into Chapters 1st a) Double click on a video in the Video Folder. 1st b) Or open a video directly via the menu File → Open Video. 2nd The video will be opened in a separate section where you can check and uncheck the chapters. 3rd Click Export Chapters Separately and choose a folder.
1 Open Terminal (in Mac) and enter the following command to navigate to your video folder. ... 2 The next command splits your video into frames and stores each one as a separate image thumbnail file. ffmpeg -i video.mp4 thumb%04d.jpg -hide_banner That’s it. ... 3 FFmpeg Split Video into Parts of Equal Duration
-i is the input file, in the above case it's a file called 'input.mp4'. -vcodec stands for the video codec to encode the output file. 'copy' means you're using the same codec as the input file. -acodec is the audio codec. output.mp4 is the output file, you can rename it as you need. Method 1. FFmpeg Split Video into Frames
ffmpeg -i input.mp3 -af silencedetect -f null - Note the default minimum length for silence is set to 2 seconds, but it can be adjusted. See ffmpeg -h filter=silencedetect. There is also a silenceremove filter.
Here's the source and list of Commonly used FFmpeg commands. If you want to create really same Chunks must force ffmpeg to create i-frame on the every chunks' first frame so you can use this command for create 0.5 second chunk. Faced the same problem earlier and put together a simple Python script to do just that (using FFMpeg).
(Edit: This tip came from https://github.com/phiresky via this issue: https://github.com/harryjackson/ffmpeg_split/issues/2)
You can get chapters using:
ffprobe -i fname -print_format json -show_chapters -loglevel error
If I was writing this again I'd use ffprobe's json options
(Original answer follows)
This is a working python script. I tested it on several videos and it worked well. Python isn't my first language but I noticed you use it so I figure writing it in Python might make more sense. I've added it to Github. If you want to improve please submit pull requests.
#!/usr/bin/env python import os import re import subprocess as sp from subprocess import * from optparse import OptionParser def parseChapters(filename): chapters = [] command = [ "ffmpeg", '-i', filename] output = "" try: # ffmpeg requires an output file and so it errors # when it does not get one so we need to capture stderr, # not stdout. output = sp.check_output(command, stderr=sp.STDOUT, universal_newlines=True) except CalledProcessError, e: output = e.output for line in iter(output.splitlines()): m = re.match(r".*Chapter #(\d+:\d+): start (\d+\.\d+), end (\d+\.\d+).*", line) num = 0 if m != None: chapters.append({ "name": m.group(1), "start": m.group(2), "end": m.group(3)}) num += 1 return chapters def getChapters(): parser = OptionParser(usage="usage: %prog [options] filename", version="%prog 1.0") parser.add_option("-f", "--file",dest="infile", help="Input File", metavar="FILE") (options, args) = parser.parse_args() if not options.infile: parser.error('Filename required') chapters = parseChapters(options.infile) fbase, fext = os.path.splitext(options.infile) for chap in chapters: print "start:" + chap['start'] chap['outfile'] = fbase + "-ch-"+ chap['name'] + fext chap['origfile'] = options.infile print chap['outfile'] return chapters def convertChapters(chapters): for chap in chapters: print "start:" + chap['start'] print chap command = [ "ffmpeg", '-i', chap['origfile'], '-vcodec', 'copy', '-acodec', 'copy', '-ss', chap['start'], '-to', chap['end'], chap['outfile']] output = "" try: # ffmpeg requires an output file and so it errors # when it does not get one output = sp.check_output(command, stderr=sp.STDOUT, universal_newlines=True) except CalledProcessError, e: output = e.output raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) if __name__ == '__main__': chapters = getChapters() convertChapters(chapters)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With