使用NumPy数组创建AudioSegment导出时出现bad sample width错误
解决wave.Error: bad sample width的问题
首先直接给结论:这个错误和数组长度是否是sampleWidth*frameRate的整数倍完全无关,核心问题出在你传入的sample_width参数类型不合法。
为什么会报错?
你用sinewave.dtype.itemsize获取的是NumPy浮点数组的元素字节数——比如如果你的正弦波是float32类型,这个值是4;如果是float64,就是8。但pydub导出音频时依赖的Python标准库wave模块,只支持整数类型的音频采样宽度,合法的取值是1(8位无符号)、2(16位有符号)、3(24位有符号)或4(32位有符号)字节。浮点类型的采样宽度不在它的支持范围内,所以直接抛出了bad sample width错误。
怎么修复?
你需要先把浮点型的NumPy数组转换为符合音频标准的整数类型数组,再创建AudioSegment实例:
- 归一化并转换为整数类型:
通常音频用16位有符号整数(PCM 16-bit)是最通用的选择,先把你的浮点正弦波值归一到[-1, 1]范围(如果还没做的话),然后乘以32767(16位有符号整数的最大值),再转换为np.int16类型。 - 用整数数组创建AudioSegment:
此时sample_width可以直接用转换后数组的itemsize,或者直接写2(因为np.int16的字节数就是2)。
修正后的代码示例
import numpy as np from pydub import AudioSegment # 假设你的sinewave是float类型的NumPy数组 # 第一步:归一化到[-1,1]并转换为16位整数 sinewave_int = (sinewave * 32767).astype(np.int16) # 创建合法的AudioSegment实例 segment = AudioSegment( data=sinewave_int.tobytes(), sample_width=sinewave_int.dtype.itemsize, frame_rate=44100, channels=1 ) # 正常导出mp3 segment.export('redgiant.mp3', format='mp3')
如果需要更高精度,也可以选择32位有符号整数(转换为np.int32,sample_width用4),但16位已经能满足绝大多数音频场景的需求,兼容性也更好。
内容的提问来源于stack exchange,提问作者triple7
相关产品推荐
相关产品推荐

