脚本如何批量提取音频波形

wen 实用脚本 1

本文目录导读:

脚本如何批量提取音频波形

  1. 使用 Python + librosa/matplotlib(推荐)
  2. 使用 FFmpeg 命令行批量处理
  3. 使用 SoX 工具批量处理
  4. 高级方案:并行处理大型数据集
  5. 安装依赖
  6. 输出示例结构
  7. 选择建议

使用 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 提取数值

根据你的具体需求选择合适的方案,如果需要进一步定制(如不同的颜色、透明度、叠加等),可以调整各自的参数。

抱歉,评论功能暂时关闭!