Python录制WAV文件无声且时长异常问题求助
问题分析与解决办法
核心问题原因
- 时长变为40秒:你给
wave文件设置了单声道(setnchannels(1)),但录制时用了双声道(sd.default.channels = 2),而且sd.rec返回的是float32格式样本(每个占4字节),你却设置setsampwidth(2)(对应16位整数,每个占2字节)。播放器按单声道、2字节样本解析时,原本10秒双声道float样本的总字节数,会被当成单声道16位整数样本,时长自然变成10×2×4÷2=40秒。 - 第三方播放器无声:
sd.rec输出的是[-1.0, 1.0]范围的float32数据,你直接把这些float字节写入wav文件,但文件设置的是16位整数格式,播放器无法正确解析,导致无声。
修正步骤
- 统一声道数:录制和保存的声道数保持一致,单声道或双声道任选其一。
- 格式转换:把float32格式的录制数据转换成16位整数,匹配wav文件的格式要求。
- 等待录制完成再写入:必须等
sd.wait()执行完再处理数据,否则写入的是未完成录制的不完整数据。
修正后的代码
import wave import sounddevice as sd import numpy as np fs = 44100 channels = 1 # 也可改为2使用双声道,需保持录制和保存参数一致 interval = 10 # 配置sounddevice参数 sd.default.samplerate = fs sd.default.channels = channels # 录制音频并等待完成 myrecording = sd.rec(int(interval * fs), dtype='float32') sd.wait() # 将float32数据转换为16位整数(映射到[-32768, 32767]区间) audio_data = (myrecording * 32767).astype(np.int16) # 写入wav文件 with wave.open('sound.wav', 'w') as obj: obj.setnchannels(channels) obj.setsampwidth(2) # 对应int16的字节长度 obj.setframerate(fs) obj.writeframesraw(audio_data.tobytes()) # 播放验证 sd.play(audio_data, fs) sd.wait()
关键细节说明
- 用
numpy做格式转换能精准映射float到整数的取值范围,避免音频失真。 - 用
with语句管理wave文件,自动处理文件关闭,避免资源泄漏。 - 必须在
sd.wait()之后处理录制数据,确保拿到完整的音频样本。
内容的提问来源于stack exchange,提问作者Devansh Garg
相关产品推荐
相关产品推荐

