4
4
import argparse
5
5
import errno
6
6
import ffmpeg
7
+ import json
7
8
import logging
8
9
import os
9
10
import re
16
17
logger .setLevel (logging .INFO )
17
18
18
19
DEFAULT_DURATION = 0.3
19
- DEFAULT_THRESHOLD = - 60
20
+ DEFAULT_THRESHOLD = - 30
20
21
21
22
parser = argparse .ArgumentParser (description = 'Split media into separate chunks wherever silence occurs' )
22
23
parser .add_argument ('in_filename' , help = 'Input filename (`-` for stdin)' )
26
27
parser .add_argument ('--start-time' , type = float , help = 'Start time (seconds)' )
27
28
parser .add_argument ('--end-time' , type = float , help = 'End time (seconds)' )
28
29
parser .add_argument ('-v' , dest = 'verbose' , action = 'store_true' , help = 'Verbose mode' )
30
+ parser .add_argument ('--metadata-filename' , help = 'Optional metadata output file' )
31
+
29
32
30
33
silence_start_re = re .compile (' silence_start: (?P<start>[0-9]+(\.?[0-9]*))$' )
31
34
silence_end_re = re .compile (' silence_end: (?P<end>[0-9]+(\.?[0-9]*)) ' )
@@ -97,7 +100,8 @@ def get_chunk_times(in_filename, silence_threshold, silence_duration, start_time
97
100
def _makedirs (path ):
98
101
"""Python2-compatible version of ``os.makedirs(path, exist_ok=True)``."""
99
102
try :
100
- os .makedirs (path )
103
+ if path :
104
+ os .makedirs (path )
101
105
except OSError as exc :
102
106
if exc .errno != errno .EEXIST or not os .path .isdir (path ):
103
107
raise
@@ -110,17 +114,28 @@ def split_audio(
110
114
silence_duration = DEFAULT_DURATION ,
111
115
start_time = None ,
112
116
end_time = None ,
117
+ metadata_filename = None ,
113
118
verbose = False ,
114
119
):
115
120
chunk_times = get_chunk_times (in_filename , silence_threshold , silence_duration , start_time , end_time )
116
121
122
+ metadata = []
117
123
for i , (start_time , end_time ) in enumerate (chunk_times ):
118
124
time = end_time - start_time
119
125
out_filename = out_pattern .format (i , i = i )
120
126
_makedirs (os .path .dirname (out_filename ))
121
127
122
- logger .info ('{}: start={:.02f}, end={:.02f}, duration={:.02f}' .format (out_filename , start_time , end_time ,
123
- time ))
128
+ start_text = '{:.02f}' .format (start_time )
129
+ end_text = '{:.02f}' .format (end_time )
130
+ duration_text = '{:.02f}' .format (time )
131
+ metadata .append ({
132
+ 'filename' : out_filename ,
133
+ 'start' : start_text ,
134
+ 'end' : end_text ,
135
+ 'duration' : duration_text ,
136
+ })
137
+ logger .info ('{}: start={}, end={}, duration={}' .format (out_filename , start_text , end_text , duration_text ))
138
+
124
139
_logged_popen (
125
140
(ffmpeg
126
141
.input (in_filename , ss = start_time , t = time )
@@ -132,6 +147,11 @@ def split_audio(
132
147
stderr = subprocess .PIPE if not verbose else None ,
133
148
).communicate ()
134
149
150
+ if metadata_filename is not None :
151
+ _makedirs (os .path .dirname (metadata_filename ))
152
+ with open (metadata_filename , 'w' ) as f :
153
+ json .dump (metadata , f )
154
+
135
155
136
156
if __name__ == '__main__' :
137
157
kwargs = vars (parser .parse_args ())
0 commit comments