44import argparse
55import errno
66import ffmpeg
7+ import json
78import logging
89import os
910import re
1617logger .setLevel (logging .INFO )
1718
1819DEFAULT_DURATION = 0.3
19- DEFAULT_THRESHOLD = - 60
20+ DEFAULT_THRESHOLD = - 30
2021
2122parser = argparse .ArgumentParser (description = 'Split media into separate chunks wherever silence occurs' )
2223parser .add_argument ('in_filename' , help = 'Input filename (`-` for stdin)' )
2627parser .add_argument ('--start-time' , type = float , help = 'Start time (seconds)' )
2728parser .add_argument ('--end-time' , type = float , help = 'End time (seconds)' )
2829parser .add_argument ('-v' , dest = 'verbose' , action = 'store_true' , help = 'Verbose mode' )
30+ parser .add_argument ('--metadata-filename' , help = 'Optional metadata output file' )
31+
2932
3033silence_start_re = re .compile (' silence_start: (?P<start>[0-9]+(\.?[0-9]*))$' )
3134silence_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
97100def _makedirs (path ):
98101 """Python2-compatible version of ``os.makedirs(path, exist_ok=True)``."""
99102 try :
100- os .makedirs (path )
103+ if path :
104+ os .makedirs (path )
101105 except OSError as exc :
102106 if exc .errno != errno .EEXIST or not os .path .isdir (path ):
103107 raise
@@ -110,17 +114,28 @@ def split_audio(
110114 silence_duration = DEFAULT_DURATION ,
111115 start_time = None ,
112116 end_time = None ,
117+ metadata_filename = None ,
113118 verbose = False ,
114119):
115120 chunk_times = get_chunk_times (in_filename , silence_threshold , silence_duration , start_time , end_time )
116121
122+ metadata = []
117123 for i , (start_time , end_time ) in enumerate (chunk_times ):
118124 time = end_time - start_time
119125 out_filename = out_pattern .format (i , i = i )
120126 _makedirs (os .path .dirname (out_filename ))
121127
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+
124139 _logged_popen (
125140 (ffmpeg
126141 .input (in_filename , ss = start_time , t = time )
@@ -132,6 +147,11 @@ def split_audio(
132147 stderr = subprocess .PIPE if not verbose else None ,
133148 ).communicate ()
134149
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+
135155
136156if __name__ == '__main__' :
137157 kwargs = vars (parser .parse_args ())
0 commit comments