You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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位整数格式,播放器无法正确解析,导致无声。

修正步骤

  1. 统一声道数:录制和保存的声道数保持一致,单声道或双声道任选其一。
  2. 格式转换:把float32格式的录制数据转换成16位整数,匹配wav文件的格式要求。
  3. 等待录制完成再写入:必须等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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 04:32:11