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}!') |
Author
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.extanyname.txtlike 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,mlsstand for hours, minutes, milliseconds respectively and are optional, depending on your requirement and the length of the video.ssstands for seconds and should always be provided, even if 0. The separators are important.Sample chapter file: