本文目录导读:

使用 Python + librosa/matplotlib(推荐)
批量提取并保存为图像
import os
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
def extract_waveform(audio_path, output_path, duration=None):
"""提取音频波形并保存为图片"""
# 加载音频
y, sr = librosa.load(audio_path, duration=duration)
# 创建波形图
plt.figure(figsize=(12, 4))
librosa.display.waveshow(y, sr=sr)
plt.title(os.path.basename(audio_path))
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.tight_layout()
# 保存图片
plt.savefig(output_path, dpi=100, bbox_inches='tight')
plt.close()
# 批量处理
input_dir = "audio_files/"
output_dir = "waveforms/"
os.makedirs(output_dir, exist_ok=True)
for file in os.listdir(input_dir):
if file.endswith(('.mp3', '.wav', '.flac', '.m4a')):
input_path = os.path.join(input_dir, file)
output_path = os.path.join(output_dir, f"{os.path.splitext(file)[0]}.png")
extract_waveform(input_path, output_path)
print(f"Processed: {file}")
提取波形数据(数值)
import librosa
import numpy as np
import json
def extract_waveform_data(audio_path):
"""提取波形数据为Numpy数组"""
y, sr = librosa.load(audio_path)
# 降低采样率以便存储
# 每100ms取一个点
samples_per_frame = int(sr * 0.1)
envelope = np.max(np.abs(y.reshape(-1, samples_per_frame)), axis=1)
return {
"sample_rate": sr,
"duration": len(y) / sr,
"waveform": envelope.tolist()
}
# 批量提取并保存为JSON
for file in os.listdir("audio_files/"):
if file.endswith(('.mp3', '.wav')):
path = os.path.join("audio_files/", file)
data = extract_waveform_data(path)
with open(f"waveforms/{file}.json", "w") as f:
json.dump(data, f)
使用 FFmpeg 命令行批量处理
提取波形图像(Python调用)
import subprocess
import os
def ffmpeg_waveform(audio_path, output_path):
"""使用FFmpeg提取波形"""
cmd = [
'ffmpeg',
'-i', audio_path,
'-filter_complex', 'showwavespic=s=1280x240:colors=blue',
'-frames:v', '1',
output_path
]
subprocess.run(cmd, check=True)
# 批量处理
for file in os.listdir("audio_files/"):
if file.endswith(('.mp3', '.wav')):
input_path = os.path.join("audio_files/", file)
output_path = os.path.join("waveforms/", f"{file}.png")
ffmpeg_waveform(input_path, output_path)
批量提取波形数据(CSV格式)
#!/bin/bash
for file in audio_files/*.wav; do
filename=$(basename "$file" .wav)
ffmpeg -i "$file" -ac 1 -filter:a "aresample=1000" \
-f f64le pipe:1 | \
python3 -c "
import sys
import numpy as np
data = np.frombuffer(sys.stdin.buffer.read(), dtype=np.float64)
np.savetxt('waveforms/${filename}.csv', data, delimiter=',')
print('Processed: ${file}')
"
done
使用 SoX 工具批量处理
提取波形数据
import subprocess
import os
def sox_waveform(audio_path, output_txt):
"""使用SoX提取波形数据"""
cmd = [
'sox',
audio_path,
'-n',
'stat',
'-d', '0.01' # 每10ms采样
]
# 需要解析输出,比较复杂
# SoX更适合直接生成图像
pass
# SoX生成波形图像
def sox_waveform_image(audio_path, output_image):
cmd = [
'sox', audio_path,
'-n', 'spectrogram',
'-o', output_image,
'-w', 'hann',
'-Y', '200',
'-X', '100'
]
subprocess.run(cmd, check=True)
高级方案:并行处理大型数据集
import concurrent.futures
from pathlib import Path
def process_single_file(file_path):
"""处理单个文件的波形提取"""
try:
y, sr = librosa.load(file_path, duration=30) # 限制时长
# 处理逻辑...
return {"file": file_path.name, "status": "success"}
except Exception as e:
return {"file": file_path.name, "status": f"error: {str(e)}"}
def batch_process_parallel(audio_dir, output_dir, max_workers=4):
"""并行批量处理"""
audio_files = list(Path(audio_dir).glob("*.[wm][ap][v3]*"))
audio_files += list(Path(audio_dir).glob("*.flac"))
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(process_single_file, f): f
for f in audio_files}
for future in concurrent.futures.as_completed(futures):
result = future.result()
print(f"{result['file']}: {result['status']}")
# 使用
batch_process_parallel("audio_files/", "waveforms/", max_workers=8)
安装依赖
# Python库 pip install librosa numpy matplotlib soundfile # 系统工具 # Ubuntu/Debian sudo apt install ffmpeg sox # macOS brew install ffmpeg sox
输出示例结构
waveforms/
├── audio1.png # 波形图像
├── audio2.wav.json # 波形数据JSON
├── audio3.csv # 波形数据CSV
└── audio4.npy # Numpy数组
选择建议
- 需要可视化:使用 librosa + matplotlib(方案1)
- 快速批量:使用 FFmpeg(方案2)
- 大型数据集:使用并行处理(方案4)
- 数据提取:使用 librosa 提取数值
根据你的具体需求选择合适的方案,如果需要进一步定制(如不同的颜色、透明度、叠加等),可以调整各自的参数。