Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Split mkv file on chapters

To split a large mkv file into a file for each chapter, run the output of this command.

files/2024/listings/split-on-chapters.sh (Source)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/sh
# File: split-on-chapters.sh
# Location: /mnt/public/Support/Programs/DVDs
# Author: bgstack15
# Startdate: 2024-02-17-7 14:22
# Title: Split mkv on chapters
# Purpose: oneliner for splitting mkv file into separate files per chapter
# History:
#    2024-02-22 moved -ss and -to before -i
# Usage:
# Reference:
#    man ffmpeg
#    slightly improved over https://superuser.com/questions/795373/split-mkv-based-on-chapters
#    https://superuser.com/questions/795373/split-mkv-based-on-chapters/1830690#1830690
#    https://stackoverflow.com/questions/14005110/how-to-split-a-video-using-ffmpeg-so-that-each-chunk-starts-with-a-key-frame/33188399#33188399
# Improve:
# Dependencies:
# Documentation:
#    This is insufficient:
#       HandBrakeCLI -c 2 -i twoeps.mkv -o 2.mkv # this does not get subtitles, and reencodes which takes a while
#   WARNING! Jellyfin+chromecast might malfunction on a video split in this manner, within the first few seconds of playback, because of the keyframe/chapter mismatch.

split_by_chapter() {
   for word in "${@}" ;
   do
      ffmpeg -i "${word}" 2>&1 | sed -n -r -e "/start.*end.*[0-9]*/{s/.*#[0-9]*:([0-9]*).* ([0-9]*\.[0-9]*).*( [0-9]*\.[0-9]*)/ffmpeg -ss \2 -to\3 -i ${word} -acodec copy -vcodec copy -scodec copy ${word%%.mkv}-chapter\1.mkv \;/g;p;}"
   done
}

split_by_chapter "${@}"

So:

$( ./split-on-chapters.sh twoepisodes.mkv )

Splitting a video file can get weird with -codec copy and -ss. If you stream at the beginning of a file split in this manner, it might never start displaying the video. There might be some way to split "correctly" by dealing with the key frames, but I spent maybe 30 minutes and couldn't figure it out. I'll just live with the consequences, of waiting a few seconds before chromecasting a split video file from Jellyfin on an android device.

References

Man pages

  1. man ffmpeg

Web links

  1. slightly improved over video - Split MKV based on Chapters - Super User
  2. video - Split MKV based on Chapters - Super User#1830690
  3. How to split a video using FFMPEG so that each chunk starts with a key frame? - Stack Overflow

Comments