Amazing-Python-Scripts
150 строк · 4.0 Кб
1from pydub import AudioSegment
2from pydub.silence import split_on_silence
3import os
4import collections
5import contextlib
6import sys
7import wave
8import os
9import webrtcvad
10
11
12def read_wave(path):
13
14with contextlib.closing(wave.open(path, 'rb')) as wf:
15num_channels = wf.getnchannels()
16assert num_channels == 1
17sample_width = wf.getsampwidth()
18assert sample_width == 2
19sample_rate = wf.getframerate()
20assert sample_rate in (8000, 16000, 32000, 48000)
21pcm_data = wf.readframes(wf.getnframes())
22return pcm_data, sample_rate
23
24
25def write_wave(path, audio, sample_rate):
26
27with contextlib.closing(wave.open(path, 'wb')) as wf:
28wf.setnchannels(1)
29wf.setsampwidth(2)
30wf.setframerate(sample_rate)
31wf.writeframes(audio)
32frames = wf.getnframes()
33return frames / float(sample_rate)
34
35
36class Frame(object):
37
38def __init__(self, bytes, timestamp, duration):
39self.bytes = bytes
40self.timestamp = timestamp
41self.duration = duration
42
43
44def frame_generator(frame_duration_ms, audio, sample_rate):
45
46n = int(sample_rate * (frame_duration_ms / 1000.0) * 2)
47offset = 0
48timestamp = 0.0
49duration = (float(n) / sample_rate) / 2.0
50while offset + n < len(audio):
51yield Frame(audio[offset:offset + n], timestamp, duration)
52timestamp += duration
53offset += n
54
55
56def vad_collector(sample_rate, frame_duration_ms,
57padding_duration_ms, vad, frames):
58
59num_padding_frames = int(padding_duration_ms / frame_duration_ms)
60ring_buffer = collections.deque(maxlen=num_padding_frames)
61triggered = False
62
63voiced_frames = []
64for frame in frames:
65is_speech = vad.is_speech(frame.bytes, sample_rate)
66
67if not triggered:
68ring_buffer.append((frame, is_speech))
69num_voiced = len([f for f, speech in ring_buffer if speech])
70
71if num_voiced > 0.9 * ring_buffer.maxlen:
72triggered = True
73
74for f, s in ring_buffer:
75voiced_frames.append(f)
76ring_buffer.clear()
77else:
78
79voiced_frames.append(frame)
80ring_buffer.append((frame, is_speech))
81num_unvoiced = len([f for f, speech in ring_buffer if not speech])
82
83if num_unvoiced > 0.9 * ring_buffer.maxlen:
84
85triggered = False
86yield b''.join([f.bytes for f in voiced_frames])
87ring_buffer.clear()
88voiced_frames = []
89if triggered:
90pass
91
92if voiced_frames:
93yield b''.join([f.bytes for f in voiced_frames])
94
95
96path = "./frontend/speech-transcription-app/public/Original data"
97if not os.path.exists(path):
98os.makedirs(path)
99print("Output folder created")
100else:
101print("Output folder already present")
102sys.exit()
103
104
105def folder(path):
106if not os.path.exists(path):
107os.makedirs(path)
108print("Output folder created")
109else:
110print("Output folder already present")
111
112
113path = "./frontend/speech-transcription-app/public/Original data"
114folder(path)
115path = "./main/save"
116folder(path)
117path = "./main/discard"
118folder(path)
119
120file_name = "./main/mod_1.wav"
121op_path = "./frontend/speech-transcription-app/public/Original data/audio_chunks"
122
123
124def main(file_name, op_path):
125
126if os.path.isdir(op_path):
127print("Output folder already present")
128else:
129os.mkdir(op_path)
130print("Output folder created")
131
132audio, sample_rate = read_wave(file_name)
133vad = webrtcvad.Vad(2)
134frames = frame_generator(30, audio, sample_rate)
135segments = vad_collector(sample_rate, 30, 300, vad, frames)
136
137for i, segment in enumerate(segments):
138path = op_path+'/'+'chunk%004d.wav' % (i+1,)
139print(' Writing %s' % (path,))
140write_wave(path, segment, sample_rate)
141
142
143# sys.argv[1]
144
145# sys.argv[2]
146file_name = "./main/mod_1.wav"
147op_path = "./frontend/speech-transcription-app/public/Original data/audio_chunks"
148main(file_name, op_path)
149
150print("Audio Splitting Done")
151