使用Librosa读写音频文件时如何保持文件大小与形状不变?
解决Librosa加载保存音频时文件大小与特征形状不一致的问题
嘿,这个问题我之前处理过好几次,核心是librosa默认的加载和保存行为会悄悄修改音频的参数,咱们来一步步把它掰回正轨:
一、先搞懂为什么会变
你遇到的两个问题根源其实是同一个:
- 文件大小变大:librosa默认会把音频重采样到22050Hz,并且用float32格式加载,保存时默认编码格式也可能和原文件(比如16bit PCM)不一致,导致体积膨胀。
- 特征形状改变:因为加载时采样率被修改,音频的总样本数变了,后续提取特征(比如梅尔频谱)时,时间步维度自然会跟着变化。
二、保持原文件参数的加载与保存方案
1. 用原生参数加载音频
修改librosa.load的参数,强制使用原文件的采样率和数据类型:
import librosa import os import soundfile as sf # 注意:librosa.output已经被官方弃用,推荐用soundfile更稳定 # 原文件路径 fname = "dog.wav" source_path = os.path.join(train_data_path, label, fname) # 先获取原文件的元信息(采样率、编码格式等) audio_info = sf.info(source_path) # 加载时禁用重采样,匹配原数据类型 y, sr = librosa.load(source_path, sr=audio_info.samplerate, dtype=audio_info.subtype)
2. 用原编码格式保存音频
用soundfile保存时指定原文件的编码 subtype,确保和原文件完全一致:
target_path = f"./input/train_test/{label}/AUG_{fname}" sf.write(target_path, y, sr, subtype=audio_info.subtype)
三、确保特征形状一致
如果你的特征(比如梅尔频谱)形状变化,要保证提取特征时的参数和原文件完全匹配:
import numpy as np # 假设原特征提取用的参数是这些(必须和之前处理原文件时完全一致) n_fft = 512 hop_length = 256 n_mels = 81 # 用原采样率的音频提取特征 mel_spect = librosa.feature.melspectrogram( y=y, sr=sr, n_fft=n_fft, hop_length=hop_length, n_mels=n_mels ) # 添加上通道维度,和原形状(99,81,1)对齐 mel_spect = mel_spect[..., np.newaxis] print(mel_spect.shape) # 现在应该和原特征形状一致
四、验证结果
保存后可以对比原文件和新文件的参数,确认一致性:
new_audio_info = sf.info(target_path) print(f"原采样率: {audio_info.samplerate} | 新采样率: {new_audio_info.samplerate}") print(f"原编码格式: {audio_info.subtype} | 新编码格式: {new_audio_info.subtype}") print(f"原样本总数: {audio_info.frames} | 新样本总数: {new_audio_info.frames}")
如果这些参数完全匹配,文件大小会和原文件几乎一致(可能差几个字节的文件头信息,属于正常情况)。
内容的提问来源于stack exchange,提问作者kim code
相关产品推荐
相关产品推荐

