forked from harryjackson/ffmpeg_split
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathffmpeg_split.py
More file actions
126 lines (107 loc) · 3.34 KB
/
ffmpeg_split.py
File metadata and controls
126 lines (107 loc) · 3.34 KB
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python
import os
import re
import subprocess as sp
from optparse import OptionParser
def parse_chapters(filename):
chapters = []
command = ["ffmpeg", '-i', filename]
output = ""
m = None
title = None
chapter_match = None
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 sp.CalledProcessError as err:
output = err.output
num = 1
for line in iter(output.splitlines()):
x = re.match(r".*title.*: (.*)", line)
if not x:
m1 = re.match(
r".*Chapter #(\d+:\d+): start (\d+\.\d+), end (\d+\.\d+).*",
line
)
title = None
else:
title = x.group(1)
if m1:
chapter_match = m1
if title and chapter_match:
m = chapter_match
else:
m = None
if m:
chapters.append({
"num": num,
"title": title,
"start": m.group(2),
"end": m.group(3)
})
num += 1
return chapters
def get_chapters(infile):
_chapters = parse_chapters(infile)
_, fext = os.path.splitext(infile)
path = os.path.dirname(os.path.realpath(infile))
newdir, fext = os.path.splitext(os.path.basename(infile))
newdir_path = os.path.join(path, newdir)
os.mkdir(newdir_path)
leading_zeros_size = len(str(len(_chapters)))
for chap in _chapters:
chap['title'] = chap['title'].replace('/', ':')
chap['title'] = chap['title'].replace("'", "\'")
outfilename = "{} - {}".format(
str(chap['num']).zfill(leading_zeros_size),
chap['title']
)
chap['outfile'] = "{}/{}{}".format(
newdir_path,
re.sub("[^-a-zA-Z0-9_.():' ]+", '', outfilename),
fext
)
chap['origfile'] = infile
return _chapters
def convert_chapters(chapters):
for chap in chapters:
command = [
"ffmpeg", '-i', chap['origfile'],
'-vcodec', 'copy',
'-acodec', 'copy',
'-metadata',
'title='+chap['title'],
'-metadata',
'track='+str(chap['num']),
'-ss', chap['start'],
'-to', chap['end'],
chap['outfile']]
try:
# ffmpeg requires an output file and so it errors
# when it does not get one
sp.check_output(command, stderr=sp.STDOUT, universal_newlines=True)
except sp.CalledProcessError as err:
raise RuntimeError(
"Command '{}' return with error (code {}): {}".format(
err.cmd, err.returncode, err.output
)
)
if __name__ == '__main__':
PARSER = OptionParser(
usage="usage: %prog [options] filename",
version="%prog 1.0"
)
PARSER.add_option(
"-f", "--file", dest="infile", help="Input File", metavar="FILE"
)
OPTIONS, _ = PARSER.parse_args()
if not OPTIONS.infile:
PARSER.error('Filename required')
CHAPTERS = get_chapters(OPTIONS.infile)
convert_chapters(CHAPTERS)