我正在使用 PyAudio 记录麦克风的输入。
既然音频对我来说录制得很好,我是否应该尝试简单地抑制它的错误消息?或者有什么办法可以解决吗?
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib audio/pcm_bluetooth.c:1613:(audioservice_expect) BT_GET_CAPABILITIES failed : Input/output error(5)
ALSA lib audio/pcm_bluetooth.c:1613:(audioservice_expect) BT_GET_CAPABILITIES failed : Input/output error(5)
ALSA lib audio/pcm_bluetooth.c:1613:(audioservice_expect) BT_GET_CAPABILITIES failed : Input/output error(5)
ALSA lib audio/pcm_bluetooth.c:1613:(audioservice_expect) BT_GET_CAPABILITIES failed : Input/output error(5)
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
您可以尝试清理您的 ALSA 配置,例如,
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2212:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
是由
/usr/share/alsa/alsa.conf
引起的:
pcm.rear cards.pcm.rear
pcm.center_lfe cards.pcm.center_lfe
pcm.side cards.pcm.side
一旦注释掉这些行,这些错误消息就会消失。您可能还想检查
~/.asoundrc
和 /etc/asound.conf
。
也就是说,其中一些消息表明您的配置有问题,尽管它们不会造成任何真正的问题。我不建议你清理
alsa.conf
,因为它本来就来自ALSA,当你更新alsa-lib时它可能会被覆盖。
Python中有一种抑制消息的方法,这里是示例代码:
#!/usr/bin/env python
from ctypes import *
import pyaudio
# From alsa-lib Git 3fd4ab9be0db7c7430ebd258f2717a976381715d
# $ grep -rn snd_lib_error_handler_t
# include/error.h:59:typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */;
# Define our error handler type
ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
print 'messages are yummy'
c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
asound = cdll.LoadLibrary('libasound.so')
# Set error handler
asound.snd_lib_error_set_handler(c_error_handler)
# Initialize PyAudio
p = pyaudio.PyAudio()
p.terminate()
print '-'*40
# Reset to default error handler
asound.snd_lib_error_set_handler(None)
# Re-initialize
p = pyaudio.PyAudio()
p.terminate()
我的计算机的输出:
messages are yummy
messages are yummy
messages are yummy
messages are yummy
messages are yummy
messages are yummy
----------------------------------------
ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream
ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
这些消息是由 alsa-lib 打印出来的,而不是 PyAudio 或 PortAudio。代码直接使用 alsa-lib
snd_lib_error_set_handler
函数来设置错误处理程序 py_error_handler
,您可以使用它来删除任何消息。
我检查了其他Python ALSA绑定,pyalsa和PyAlsaAudio,它们不支持设置错误处理程序。然而,PortAudio 上存在问题,所有 ALSA 错误消息之前似乎都被抑制了。
以上所有内容都是正确的,也是一个很好的解决方案。我来这里只是为了建议一种更好的重用错误处理程序代码的方法:
from ctypes import *
from contextlib import contextmanager
import pyaudio
ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
pass
c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
@contextmanager
def noalsaerr():
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
yield
asound.snd_lib_error_set_handler(None)
完成此操作后,您可以通过使用
noalsaerr
上下文来重新使用错误处理程序:
with noalsaerr():
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=1)
...
我也面临着同样的问题。
只需在命令末尾添加
2>/dev/null
就解决了我的问题。我只是想抑制错误消息,它成功了。
例如:
python marvin.py 2>/dev/null
这些看起来像正常的调试消息,因为它指出如何在您的系统上运行。我不认为你有任何理由不应该压制他们。
您可能可以以某种方式关闭对
jack
服务器、蓝牙设备、环绕声等的检测,但这不是必需的,而且您可能会把事情搞砸。不要搞乱正在运行的东西!
这将在创建 pyaudio 对象时抑制错误消息
import time, os, sys, contextlib
@contextlib.contextmanager
def ignoreStderr():
devnull = os.open(os.devnull, os.O_WRONLY)
old_stderr = os.dup(2)
sys.stderr.flush()
os.dup2(devnull, 2)
os.close(devnull)
try:
yield
finally:
os.dup2(old_stderr, 2)
os.close(old_stderr)
...
...
with ignoreStderr():
self._audio_interface = pyaudio.PyAudio()
如果您的默认音频子系统是 Pulseaudio(常见于 Fedora、Ubuntu、Debian),最好正确地重新编译 PyAudio 和底层 C 库 Portaudio,仅支持 Pulseaudio,而无需 Jack 和其他子系统。
小补充点:
就我而言,这仍然抛出以下 ALSA 错误:
同时删除来自 JACK 的消息 (基于 @livibetter 对 libasound.so 的建议,但此处使用 libjack.so.0)
# Define our error handler type
JACK_ERROR_HANDLER_FUNC = CFUNCTYPE(None)
def py_jack_error_handler():
pass
jack_c_error_handler = JACK_ERROR_HANDLER_FUNC(py_jack_error_handler)
jack = cdll.LoadLibrary('libjack.so.0')
# Set error handler
jack.jack_set_error_function(jack_c_error_handler)