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

PyAudio设置立体声录制却始终输出单声道问题求助

问题

我使用支持双输入通道的Scarlett 2i2 USB音频设备,通过以下PyAudio代码录制音频时,明明初始化设置了channels=2,但最终生成的音频始终是单声道。附上代码和设备信息,求排查原因。

代码

import pyaudio
import wave

class AudioRecorder:
    def __init__(self, chunk=1024, sample_format=pyaudio.paInt16, channels=2, fs=44100, filename="output.wav"):
        self.chunk = chunk
        self.sample_format = sample_format
        self.channels = channels
        self.fs = fs
        self.filename = filename
        self.wave = None
        self.p = pyaudio.PyAudio()
        self.frames = []
        self.stream = None

    def record(self):
        def record_callback(in_data, frame_count, time_info, status):
            # self.frames.append(in_data)
            self.wave.writeframes(in_data)
            return (None, pyaudio.paContinue)

        print(f'{self.p.get_default_input_device_info()}')            
        print('Start Recording...\n')

        # init wave file
        self.wave = wave.open(self.filename, 'wb')
        self.wave.setnchannels(self.channels)  # Stereo
        self.wave.setsampwidth(self.p.get_sample_size(self.sample_format))
        self.wave.setframerate(self.fs)

        self.stream = self.p.open(format=self.sample_format,
                            channels=self.channels,
                            rate=self.fs,
                            frames_per_buffer=self.chunk,
                            input=True,
                            stream_callback=record_callback)     

        self.stream.start_stream()   
    def stop(self):
        if self.stream is not None and self.stream.is_active():
            self.stream.stop_stream()
            self.stream.close()
            self.p.terminate()
            self.wave.close()
            print('Finished recording')
        else:
            print('Stream is not active')            

if __name__ == "__main__":
    recorder = AudioRecorder()
    while True:
        print('Press 1 to start recording')
        print('Press 2 to stop recording')
        choice = input('Enter your choice: ')
        if choice == '1':
            recorder.record()
            continue
        elif choice == '2':
            recorder.stop()
            break

设备信息

{'index': 1, 'structVersion': 2, 'name': 'Scarlett 2i2 USB', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.01, 'defaultLowOutputLatency': 0.0033385416666666667, 'defaultHighInputLatency': 0.1, 'defaultHighOutputLatency': 0.005671875, 'defaultSampleRate': 192000.0}


排查与修复方案

1. 指定正确的输入设备

当前代码默认使用系统默认输入设备,可能并非Scarlett 2i2。在p.open()中显式指定设备索引:

self.stream = self.p.open(format=self.sample_format,
                    channels=self.channels,
                    rate=self.fs,
                    frames_per_buffer=self.chunk,
                    input=True,
                    input_device_index=1,  # 设备信息中index为1
                    stream_callback=record_callback)

2. 修复线程不安全的文件写入

wave.writeframes()并非线程安全操作,直接在回调中调用可能导致数据损坏。改为缓存数据后统一写入:

def record_callback(in_data, frame_count, time_info, status):
    self.frames.append(in_data)
    return (None, pyaudio.paContinue)

# 在stop()方法中统一写入
def stop(self):
    if self.stream is not None and self.stream.is_active():
        self.stream.stop_stream()
        self.stream.close()
        self.p.terminate()
        # 写入缓存的音频数据
        self.wave.writeframes(b''.join(self.frames))
        self.wave.close()
        self.frames.clear()  # 清空缓存以便下次录制
        print('Finished recording')
    else:
        print('Stream is not active')

3. 避免重复录制初始化

当前多次按下1会重复创建wave文件和stream,添加判断防止重复启动:

def record(self):
    if self.stream and self.stream.is_active():
        print('Recording already in progress')
        return
    # 剩余原代码...

4. 验证硬件与系统设置

  • 确认Scarlett 2i2的两个输入通道旋钮已打开,且有音频输入(如连接麦克风并打开增益)。
  • 在系统音频设置中,检查Scarlett 2i2的输入配置是否为立体声,未被强制设置为单声道。

内容的提问来源于stack exchange,提问作者Bagusflyer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:12:19