-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsplit.py
More file actions
83 lines (72 loc) · 3.04 KB
/
Copy pathsplit.py
File metadata and controls
83 lines (72 loc) · 3.04 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
from pydub import AudioSegment, silence
import math
import os
from pathlib import Path
def split_audio_by_silence(audio, min_silence_len=2000, silence_thresh=-40, keep_silence=500):
"""
Splits an AudioSegment using silence as boundary.
Parameters:
- audio: AudioSegment object.
- min_silence_len: Minimum duration (ms) of silence to be considered a split point.
- silence_thresh: Silence threshold in dBFS.
- keep_silence: Duration (ms) of silence to retain at the start and end of each chunk.
Returns:
- chunks: List of AudioSegment objects.
- boundaries: List of tuples (start_ms, end_ms) for each chunk.
"""
# Detect silence intervals
silent_intervals = silence.detect_silence(
audio,
min_silence_len=min_silence_len,
silence_thresh=silence_thresh
)
# Flatten silent_intervals into boundaries
split_points = [0] + [end for _, end in silent_intervals] + [len(audio)]
print(split_points)
# Remove too-close split points (edge case)
split_points = sorted(list(set(split_points)))
# Generate audio chunks
chunks = []
boundaries = []
for i in range(len(split_points) - 1):
start = max(0, split_points[i] - keep_silence)
end = min(len(audio), split_points[i+1] + keep_silence)
chunk = audio[start:end]
chunks.append(chunk)
boundaries.append((start, end))
return chunks, boundaries
# 示例:加载音频并保存切割结果
def save_by_silence(audio_file:str, output_dir: str=None, min_silence_len=2000, silence_thresh=-40, keep_silence=500):
if output_dir is None:
p = Path(audio_file)
p.parent.joinpath(p.stem).mkdir(exist_ok=True)
output_dir = p.parent.joinpath(p.stem)
else:
output_dir = Path(output_dir)
output_dir.mkdir(exist_ok=True)
audio = AudioSegment.from_file(audio_file)
chunks, boundaries = split_audio_by_silence(audio, min_silence_len, silence_thresh, keep_silence)
os.makedirs(output_dir, exist_ok=True)
for i, (chunk, (start, end)) in enumerate(zip(chunks, boundaries)):
output_path = output_dir.joinpath(f"output_{i:03d}.wav")
chunk.export(output_path, format="wav")
def save_by_segment(audio_file : str, output_dir : str=None):
if output_dir is None:
p = Path(audio_file)
p.parent.joinpath(p.stem).mkdir(exist_ok=True)
output_dir = p.parent.joinpath(p.stem)
else:
output_dir = Path(output_dir)
output_dir.mkdir(exist_ok=True)
audio = AudioSegment.from_file(audio_file)
segment_length = 30 * 1000
total_segments = math.ceil(len(audio) / segment_length)
for i in range(total_segments):
output_path = output_dir.joinpath(f"output_{i:03d}.wav")
start = i * segment_length
end = min((i + 1) * segment_length, len(audio))
segment = audio[start:end]
segment.export(output_path, format="wav")
if __name__ == "__main__":
audio_file = "/home/muyun/VScode/project/ASR/data/audio/20250323.wav"
save_by_segment(audio_file=audio_file)