如何使用python.wave正确将列表中的帧写入单声道WAV文件
解决Python wave模块写入WAV文件出现噪音的问题
原代码的核心问题
- 错误拆分帧结构:
list(frames)会把二进制帧拆成单个字节元素,而你设置的采样宽度是2字节(16位),循环将每个字节转成2字节写入,相当于每个原始字节被强制扩展为2字节,完全破坏了音频采样的结构,这是噪音产生的主要原因。 - 参数设置错误:
setparams的第四个参数是采样帧数,你传入的len(binary_data)是字节数,两者不匹配会导致文件播放时长、节奏异常,进一步引发噪音。 - 硬编码采样率:直接指定48000采样率,若原文件采样率不同,会导致播放速度失真,也会产生类似噪音的问题。
正确实现方式
- 读取原音频的参数,仅修改声道数为1,保留采样宽度、采样率等关键参数
- 按需处理多声道转单声道的逻辑,保证每个采样的字节完整性
- 按正确的采样帧数和二进制格式写入文件
修正后的代码
import wave # 读取原音频文件,自动管理文件句柄 with wave.open('1.wav', 'rb') as audio_file: # 获取原文件参数:声道数、采样宽度、采样率、总帧数等 original_params = audio_file.getparams() n_channels, sampwidth, framerate, n_frames = original_params[:4] # 读取全部帧数据 frames = audio_file.readframes(n_frames) # 处理单声道数据:多声道转单声道,单声道直接复用 if n_channels > 1: # 以立体声转左声道为例:每n_channels*sampwidth字节取前sampwidth字节 mono_frames = b''.join([ frames[i:i+sampwidth] for i in range(0, len(frames), sampwidth * n_channels) ]) else: mono_frames = frames # 写入单声道WAV文件 with wave.open('output.wav', 'wb') as output_file: # 构造新参数:仅修改声道数为1,其余保留原文件设置 new_params = (1, sampwidth, framerate, len(mono_frames)//sampwidth, original_params[4], original_params[5]) output_file.setparams(new_params) output_file.writeframes(mono_frames)
关键说明
- 使用
with语句自动处理文件打开/关闭,避免资源泄漏 - 复用原文件的采样宽度、采样率等参数,保证音频基础格式一致
- 多声道转单声道时,按采样宽度提取对应声道的连续字节,确保每个采样的完整性
- 计算采样帧数时用
总字节数//采样宽度,保证参数与实际数据匹配
内容的提问来源于stack exchange,提问作者Icold
相关产品推荐
相关产品推荐

