将Win10音频网络Python脚本移植到Ubuntu遇ALSA/JACK问题求助
问题描述
我编写了一套Python程序,分为Client和Receiver两部分,功能是捕获麦克风输入并通过私有网络传输至另一台机器,再映射到该机器的扬声器播放。这套程序在Windows 10机器间运行正常,但在Ubuntu 22.04 LTS + Ubuntu Studio插件的VirtualBox虚拟机(桥接网络,已授权主机音频访问)中作为发送端测试时,出现大量ALSA和JACK相关错误,安装Ubuntu Studio的ALSA和JACK驱动后问题依旧。
启动脚本的错误输出如下:
ALSA lib pcm_dmix.c:1032:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71 ALSA lib setup.c:547:(add_elem) Cannot obtain info for CTL elem (MIXER,'IEC958 Playback Default',0,0,0): No such file or directory ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib pcm.c:2664:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card' ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card' ALSA lib pcm_dmix.c:1032:(snd_pcm_dmix_open) unable to open slave Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock /home/ben/Desktop/reciever.py:42: DeprecationWarning: setDaemon() is deprecated, set the daemon attribute instead udpThread .setDaemon(True) /home/ben/Desktop/reciever.py:43: DeprecationWarning: setDaemon() is deprecated, set the daemon attribute instead AudioThread.setDaemon(True) ^[[1;2D^CTraceback (most recent call last): File "/home/ben/Desktop/reciever.py", line 46, in <module> udpThread .join() File "/usr/lib/python3.10/threading.py", line 1096, in join self._wait_for_tstate_lock() File "/usr/lib/python3.10/threading.py", line 1116, in _wait_for_tstate_lock if lock.acquire(block, timeout): KeyboardInterrupt
优先处理方向与解决方法
1. 优先解决JACK服务启动失败问题
从错误日志看,JACK服务无法启动是核心阻塞点,Python音频库大概率在尝试连接JACK但失败,进而触发后续ALSA错误。
解决步骤:
配置JACK权限:
将当前用户添加到音频相关用户组,确保权限足够:sudo usermod -aG audio $USER sudo usermod -aG jackuser $USER注销后重新登录生效。
手动启动JACK并排查错误:
终端执行jackd -d alsa,查看具体启动报错。常见问题及处理:- VirtualBox音频控制器设置:进入虚拟机设置,将音频控制器改为Intel HD Audio,并确认"启用音频输入"已勾选。
- 指定正确音频设备启动:先执行
arecord -l查看系统识别到的麦克风设备,再用对应设备编号启动JACK:
其中jackd -d alsa -d hw:0hw:0替换为arecord -l输出中的实际设备编号。
用QjackCtl图形化调试:
打开Ubuntu Studio自带的QjackCtl,在"设置"中选择正确的音频设备,点击"启动"后查看日志面板的详细错误,针对性调整采样率(VirtualBox建议44100Hz)、缓冲区大小(建议1024)等参数。
2. 修复ALSA无效设备配置
日志中Unknown PCM错误是系统尝试加载不存在的音频设备(如HDMI、后置音箱等)导致,可通过配置屏蔽这些无效项:
- 编辑
~/.asoundrc(用户级配置)或/etc/asound.conf(系统级配置),添加以下内容:
其中pcm.!default { type hw card 0 } ctl.!default { type hw card 0 }card 0替换为aplay -l输出中的主音频设备编号,保存后重启ALSA服务:sudo alsa force-reload
3. 强制Python音频库使用ALSA后端
如果JACK配置仍有问题,可强制Python音频库跳过JACK直接使用ALSA:
- 以pyaudio为例,初始化时指定正确设备:
import pyaudio p = pyaudio.PyAudio() # 列出所有可用设备,找到麦克风对应的编号 for i in range(p.get_device_count()): print(p.get_device_info_by_index(i)) # 用正确设备初始化输入流 stream = p.open(format=pyaudio.paInt16, channels=1, rate=44100, input=True, input_device_index=0) # 替换为实际麦克风设备编号 - 对于sounddevice库,设置环境变量强制使用ALSA:
import os os.environ['SOUNDDEVICE_BACKEND'] = 'alsa' import sounddevice as sd
4. 修复代码中的废弃API警告
将代码中的setDaemon()替换为daemon属性:
udpThread.daemon = True AudioThread.daemon = True
内容的提问来源于stack exchange,提问作者Bencosterton
相关产品推荐
相关产品推荐

