Last active
April 8, 2022 15:05
-
-
Save amzon-ex/7913b503fa2e08f33946863fc26b8366 to your computer and use it in GitHub Desktop.
Create chapters in a video using ffmpeg+python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import subprocess | |
import re | |
argslen = len(sys.argv) | |
vidfile = sys.argv[1] | |
chapfile = sys.argv[2] | |
mdfile = 'mdfile.txt' | |
subprocess.call(['ffmpeg', '-y', '-v', 'error', '-i', vidfile, '-f', 'ffmetadata', mdfile]) | |
outsub = subprocess.check_output(['ffprobe', '-v', 'error',\ | |
'-show_entries', 'format=duration',\ | |
'-of', 'default=noprint_wrappers=1:nokey=1',\ | |
vidfile]).decode() | |
endts = float(outsub.strip()) | |
print(f'Reading chapters from {chapfile}...') | |
chapdata = [] | |
with open(chapfile, 'r') as f: | |
for line in f: | |
ts, cname = line.split(" ", 1) | |
tsparts = list(filter(None, re.split("[.:]+", ts))) | |
tsargs = len(tsparts) | |
multiplier = 1 | |
tss = 0 | |
# Check if milliseconds argument given | |
if(ts.find('.') != -1): | |
tsms = float(tsparts[-1]) | |
for part in range(2, tsargs + 1): | |
tss += multiplier * float(tsparts[-part]) | |
multiplier *= 60 | |
tsms = 1000 * tss + tsms | |
else: | |
for part in range(1, tsargs + 1): | |
tss += multiplier * float(tsparts[-part]) | |
multiplier *= 60 | |
tsms = 1000 * tss | |
chapdata.append([int(tsms), cname]) | |
chapnum = len(chapdata) | |
chaptext = "" | |
for i in range(chapnum): | |
cstart = chapdata[i][0] | |
if (i < (chapnum - 1)): | |
cend = chapdata[i+1][0] - 1 | |
else: | |
cend = int(1000 * endts) | |
cname = chapdata[i][1] | |
chaptext += f""" | |
[CHAPTER] | |
TIMEBASE=1/1000 | |
START={cstart} | |
END={cend} | |
title={cname}""" | |
with open(mdfile, 'a') as f: | |
f.write(chaptext) | |
vidfilename, vidfileformat = vidfile.split('.', 1) | |
modvidfile = vidfilename + '_wch.' + vidfileformat | |
outstatus = subprocess.run(['ffmpeg', '-loglevel', 'error', '-stats', '-i', vidfile, '-i', mdfile,\ | |
'-map_metadata', '1', '-codec', 'copy',\ | |
modvidfile]) | |
if (outstatus.returncode == 0): | |
print(f'Chapters successfully written to {modvidfile}!') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This short, crude script takes in as argument
anyvideo.ext
anyname.txt
like so:
You need to have python installed (of course, silly!), and ffmpeg: it should also be added to path.
To view chapters, you need a suitable player. VLC is able to display chapters - I don't know of any other (yet).
Chapters text file should be in the format:
hh
,mm
,mls
stand for hours, minutes, milliseconds respectively and are optional, depending on your requirement and the length of the video.ss
stands for seconds and should always be provided, even if 0. The separators are important.Sample chapter file: