10
10
import subprocess
11
11
import sys
12
12
13
+
13
14
logging .basicConfig (level = logging .INFO , format = '%(message)s' )
14
15
logger = logging .getLogger (__file__ )
15
16
logger .setLevel (logging .INFO )
24
25
parser .add_argument ('--silence-duration' , default = DEFAULT_DURATION , type = float , help = 'Silence duration' )
25
26
parser .add_argument ('--start-time' , type = float , help = 'Start time (seconds)' )
26
27
parser .add_argument ('--end-time' , type = float , help = 'End time (seconds)' )
27
-
28
+ parser . add_argument ( '-v' , dest = 'verbose' , action = 'store_true' , help = 'Verbose mode' )
28
29
29
30
silence_start_re = re .compile (' silence_start: (?P<start>[0-9]+(\.?[0-9]*))$' )
30
31
silence_end_re = re .compile (' silence_end: (?P<end>[0-9]+(\.?[0-9]*)) ' )
31
32
total_duration_re = re .compile (
32
33
'size=[^ ]+ time=(?P<hours>[0-9]{2}):(?P<minutes>[0-9]{2}):(?P<seconds>[0-9\.]{5}) bitrate=' )
33
34
34
35
36
+ def _logged_popen (cmd_line , * args , ** kwargs ):
37
+ logger .debug ('Running command: {}' .format (subprocess .list2cmdline (cmd_line )))
38
+ return subprocess .Popen (cmd_line , * args , ** kwargs )
39
+
40
+
35
41
def get_chunk_times (in_filename , silence_threshold , silence_duration , start_time = None , end_time = None ):
36
42
input_kwargs = {}
37
43
if start_time is not None :
@@ -41,17 +47,20 @@ def get_chunk_times(in_filename, silence_threshold, silence_duration, start_time
41
47
if end_time is not None :
42
48
input_kwargs ['t' ] = end_time - start_time
43
49
44
- args = (ffmpeg
45
- .input (in_filename , ** input_kwargs )
46
- .filter_ ('silencedetect' , n = '{}dB' .format (silence_threshold ), d = silence_duration )
47
- .output ('-' , format = 'null' )
48
- .get_args ()
50
+ p = _logged_popen (
51
+ (ffmpeg
52
+ .input (in_filename , ** input_kwargs )
53
+ .filter_ ('silencedetect' , n = '{}dB' .format (silence_threshold ), d = silence_duration )
54
+ .output ('-' , format = 'null' )
55
+ .compile ()
56
+ ) + ['-nostats' ], # FIXME: use .nostats() once it's implemented in ffmpeg-python.
57
+ stderr = subprocess .PIPE
49
58
)
50
- p = subprocess .Popen (['ffmpeg' ] + args , stderr = subprocess .PIPE )
51
59
output = p .communicate ()[1 ].decode ('utf-8' )
52
60
if p .returncode != 0 :
53
61
sys .stderr .write (output )
54
62
sys .exit (1 )
63
+ logger .debug (output )
55
64
lines = output .splitlines ()
56
65
57
66
# Chunks start when silence ends, and chunks end when silence starts.
@@ -93,13 +102,15 @@ def _makedirs(path):
93
102
if exc .errno != errno .EEXIST or not os .path .isdir (path ):
94
103
raise
95
104
105
+
96
106
def split_audio (
97
107
in_filename ,
98
108
out_pattern ,
99
109
silence_threshold = DEFAULT_THRESHOLD ,
100
110
silence_duration = DEFAULT_DURATION ,
101
111
start_time = None ,
102
112
end_time = None ,
113
+ verbose = False ,
103
114
):
104
115
chunk_times = get_chunk_times (in_filename , silence_threshold , silence_duration , start_time , end_time )
105
116
@@ -110,18 +121,21 @@ def split_audio(
110
121
111
122
logger .info ('{}: start={:.02f}, end={:.02f}, duration={:.02f}' .format (out_filename , start_time , end_time ,
112
123
time ))
113
- subprocess . Popen (
124
+ _logged_popen (
114
125
(ffmpeg
115
126
.input (in_filename , ss = start_time , t = time )
116
127
.output (out_filename )
117
128
.overwrite_output ()
118
129
.compile ()
119
130
),
120
- stdout = subprocess .PIPE ,
121
- stderr = subprocess .PIPE ,
131
+ stdout = subprocess .PIPE if not verbose else None ,
132
+ stderr = subprocess .PIPE if not verbose else None ,
122
133
).communicate ()
123
134
124
135
125
136
if __name__ == '__main__' :
126
- args = parser .parse_args ()
127
- split_audio (** vars (args ))
137
+ kwargs = vars (parser .parse_args ())
138
+ if kwargs ['verbose' ]:
139
+ logging .basicConfig (level = logging .DEBUG , format = '%(levels): %(message)s' )
140
+ logger .setLevel (logging .DEBUG )
141
+ split_audio (** kwargs )
0 commit comments