Split Mkv Based on Chapters

Split Mkv Based on Chapters

I have a long MKV file which I want to split into its individual chapters.

Running ffmpeg -i long.mkv gives me all the information about the chapters embedded in the file:

 Duration: 01:23:45.80, start: 0.000000, bitrate: 8116 kb/s
    Chapter #0.0: start 0.000000, end 235.000000
    Metadata:
      title           : Chapter 01
    Chapter #0.1: start 235.000000, end 450.160000
    Metadata:
      title           : Chapter 02
    Chapter #0.2: start 450.160000, end 789.400000
    ...

There are 10 chapters in the file - I want to end up with 10 separate files.

It looks like -map_chapters might to something similar - but I can't find any documentation on it.

2

5 Answers

split mkv video by chapters using mkvmerge

mkvmerge -o output.mkv --split chapters:all input.mkv
2

I can't find a reliable way to do this with ffmpeg / avconv - but I can find a way to do this with HandBrakeCLI.

 HandBrakeCLI -c 3 -i whatever.mkv -o 3.mkv

Will extract chapter 3 from an mkv.

2

brute force solution, hehe:

ffmpeg -i long.mkv | grep 'start.*end.*[0-9]*' | sed -r 's/.*#[0-9]\.([0-9]*).* ([0-9]*\.[0-9]*).*( [0-9]*\.[0-9]*)/ ffmpeg -i long.mkv -ss \2 -to\3 -acodec copy -vcodec copy chapter\

You can add xargs to run the output in cowboy style: | xargs -I cmd bash -c 'cmd'

This is my solution, it works well on ubuntu-16.04.02-LTS. It is based on another posted solution but has improved handling of chapters and the generated files for each chapter.

This is a sample execution:

$ mkv-split-chapters some-mkv-file.mkv
Filename: some-mkv-file
Extension: mkv
Filedir: .
ffmpeg -i some-mkv-file.mkv -ss 0.000000 -to 394.800000 -acodec copy -vcodec copy ./some-mkv-file-#00.mkv
[...]
ffmpeg -i some-mkv-file.mkv -ss 394.800000 -to 767.160000 -acodec copy -vcodec copy ./some-mkv-file-#01.mkv
[...]
ffmpeg -i some-mkv-file.mkv -ss 757.160000 -to 1216.720000 -acodec copy -vcodec copy ./some-mkv-file-#02.mkv
[...]

This is the script:

$ cat /usr/local/bin/mkv-split-chapters
#!/bin/bash
file="$1"
if [ -z "$file" ]; then
        echo "Missing file argument!"
        exit 1
fi

filename=$(basename "$file")
fileextension="${filename##*.}"
filename="${filename%.*}"
filedir=$(dirname "$file")
echo "Filename: $filename"
echo "Extension: $fileextension"
echo "Filedir: $filedir"
ffmpeg -i $file 2>&1 | grep 'Chapter' | grep 'start' | grep ', end' | awk "{
        chapter=\$2
        # replace : with nil
        gsub(/:/, \"\", chapter)
        start=\$4
        # remove everything but 0-9.
        gsub(/[^0123456789\.]/, \"\", start)
        end=\$6
        command=sprintf(\"ffmpeg -i $file -ss %s -to %s -acodec copy -vcodec copy $filedir/$filename-%s.$fileextension\n\", start, end, chapter)
        print(command)
        system(command)
}"

The script is also available here:

You can use the open source GUI program called LosslessCut. It losslessly cuts popular formats like mp4 and mkv instantly without reencoding the video. It works really well.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

David Miller
Author

David Miller

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.