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

树莓派Zero 2W中rpi_ws281x与pyaudio的sudo权限冲突问题求助

树莓派Zero 2W上PyAudio与rpi_ws281x的权限冲突解决方案

问题背景

在树莓派Zero 2W上尝试用pyaudio获取音频控制rpi_ws281x驱动的LED灯带时,遇到权限冲突:

  • 非sudo运行脚本:导入rpi_ws281x时报错“无法打开/dev/mem,权限被拒绝”,必须用sudo才能控制灯带
  • sudo运行脚本:pyaudio报错OSError: [Errno -9996] Invalid input device (no default output device)

已通过最小示例验证:rpi_ws281x仅sudo可用,pyaudio仅非sudo可用。

方案一:配置PulseAudio允许sudo下的PyAudio连接

sudo运行时PyAudio无法访问PulseAudio是因为权限隔离,可通过以下步骤解决:

  1. 获取当前用户的PulseAudio路径
    在非sudo终端执行,获取PulseAudio的运行时目录:

    echo $XDG_RUNTIME_DIR/pulse/native
    

    通常输出为/run/user/1000/pulse/native(1000是pi用户的UID)

  2. 带环境变量sudo运行脚本
    运行脚本时指定PulseAudio的环境变量,让sudo进程能访问用户的音频服务:

    sudo XDG_RUNTIME_DIR=/run/user/1000 PULSE_COOKIE=/home/pi/.config/pulse/cookie python3 your_script.py
    

    替换your_script.py为你的脚本文件名,若用户UID不是1000,对应修改路径中的数字。

  3. 验证配置
    运行以下测试脚本确认sudo下能识别音频设备:

    import pyaudio
    p = pyaudio.PyAudio()
    print("可用输入设备数量:", p.get_device_count())
    for i in range(p.get_device_count()):
        dev_info = p.get_device_info_by_index(i)
        print(f"设备{i}: {dev_info['name']}")
    p.terminate()
    

    若能输出设备列表,说明配置生效。

方案二:拆分程序为非sudo音频采集进程 + sudo LED控制进程

如果方案一无法解决,可拆分程序为两个独立进程,通过高效IPC通信传递数据,满足每秒20次的需求:

进程分工

  • 非sudo进程:负责pyaudio音频采集与预处理,发送数据给LED控制进程
  • sudo进程:负责接收数据,通过rpi_ws281x控制灯带

高效通信方式推荐

1. Unix域套接字(Unix Domain Socket)

本地进程通信速度快、延迟低,Python原生支持socket模块:

LED控制进程(sudo运行):

import socket
import os
from rpi_ws281x import PixelStrip, Color

# 初始化灯带(根据硬件配置修改)
LED_COUNT = 30
LED_PIN = 18
LED_FREQ_HZ = 800000
LED_DMA = 10
LED_BRIGHTNESS = 255
LED_INVERT = False
strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS)
strip.begin()

# 创建套接字
SOCKET_PATH = "/tmp/audio_led_socket"
try:
    os.unlink(SOCKET_PATH)
except OSError:
    if os.path.exists(SOCKET_PATH):
        raise

server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server_socket.bind(SOCKET_PATH)
server_socket.listen(1)

print("等待音频进程连接...")
connection, _ = server_socket.accept()
try:
    while True:
        # 接收音量数据(示例为1字节,范围0-255)
        data = connection.recv(1)
        if not data:
            break
        volume = ord(data)
        # 根据音量设置灯带颜色
        for i in range(strip.numPixels()):
            strip.setPixelColor(i, Color(volume, 0, 0))
        strip.show()
finally:
    connection.close()
    os.unlink(SOCKET_PATH)

音频采集进程(非sudo运行):

import socket
import pyaudio
import numpy as np

# 音频配置
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100

p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

# 连接套接字
SOCKET_PATH = "/tmp/audio_led_socket"
client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
client_socket.connect(SOCKET_PATH)

try:
    while True:
        data = stream.read(CHUNK)
        # 计算音量并映射到0-255范围
        audio_data = np.frombuffer(data, dtype=np.int16)
        volume = int(min(np.abs(audio_data).mean() / 32768 * 255, 255))
        # 发送数据
        client_socket.sendall(bytes([volume]))
finally:
    stream.stop_stream()
    stream.close()
    p.terminate()
    client_socket.close()

2. 共享内存(Shared Memory)

若需传递更大数据,可使用multiprocessing模块的Value/Array或mmap库,实现低延迟实时数据共享。

运行方式

  1. 先sudo启动LED控制进程:sudo python3 led_controller.py
  2. 再非sudo启动音频采集进程:python3 audio_capture.py

附:sudo下PyAudio完整报错信息

ALSA lib pcm_dsnoop.c:638:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm_dmix.c:1075:(snd_pcm_dmix_open) unable to open slave
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.USB-Audio.pcm.hdmi.0:CARD=1,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:4745:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5233:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM hdmi
ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.USB-Audio.pcm.hdmi.0:CARD=1,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:4745:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5233:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM hdmi
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2660:(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 pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Access denied

ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Access denied

ALSA lib pcm_a52.c:823:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_dmix.c:1075:(snd_pcm_dmix_open) unable to open slave
ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Access denied

ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Access denied

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
Recording
Traceback (most recent call last):
  File "/home/pi/Documents/test.py", line 15, in <module>
    stream = p.open(format=sample_format,
  File "/home/pi/environments/flask-env/lib/python3.9/site-packages/pyaudio.py", line 754, in open
    stream = Stream(self, *args, **kwargs)
  File "/home/pi/environments/flask-env/lib/python3.9/site-packages/pyaudio.py", line 445, in __init__
    self._stream = pa.open(**arguments)
OSError: [Errno -9996] Invalid input device (no default output device)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:05:54