【问题标题】:PyAudio working, but spits out error messages each timePyAudio 工作,但每次都吐出错误消息
【发布时间】:2015-11-22 11:12:55
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: python alsa pyaudio


    【解决方案1】:

    您可以尝试清理您的 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 上有an issue,之前似乎所有的 ALSA 错误消息都被抑制了。

    【讨论】:

    • 这不会消除来自 JACK 的消息,对吧?
    • 我想知道要注释掉的那些行实际上是什么意思,以便了解它们的删除是否会产生其他影响
    【解决方案2】:

    以上所有内容都是正确的,并且是一个很好的解决方案。我只是来这里建议一种更好的方法来重用错误处理程序代码:

    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)
    ...
    

    【讨论】:

    • 这绝对是一个优雅的解决方案。
    【解决方案3】:

    这些看起来像正常的调试消息,因为它会确定如何在您的系统上运行。我看不出有什么理由不应该压制他们。

    您可能会以某种方式关闭对jack 服务器、蓝牙设备、环绕声等的检测,但这不是必需的,您可能会搞砸。不要乱搞正在工作的东西!

    【讨论】:

    • 感谢您的建议!我的问题是,脚本显示需要记录的文本。一旦您点击记录,该文本基本上就会被这些调试消息排除在外。
    • 如果您的问题是如何抑制它们,请尝试将 stderr 重定向到文件。 stderr = open(logfile, 'wb') 然后sys.stderr = stderr。让我知道它是否有效。
    • 这似乎有道理,但没有效果。例如,消息是否有可能来自另一个输出流?
    【解决方案4】:

    【讨论】:

    【解决方案5】:

    如果您的默认音频子系统是 Pulseaudio(Fedora、Ubuntu、Debian 常见),最好在没有 Jack 和其他子系统的情况下正确重新编译 PyAudio 和底层 C 库 Portaudio,仅支持 Pulseaudio。

    【讨论】:

      【解决方案6】:

      这将在创建 pyaudio 对象时抑制错误消息

      it comes from Matthais's awesome post

      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()
      

      【讨论】:

      • 很好,为我工作...谢谢
      【解决方案7】:

      小加点:

      1. 确保将 alsa.conf 复制到另一个备份位置。
      2. 确保在编辑 alsa.conf 时对编辑器进行 Sudo(例如 sudo vi alsa.conf),这样您就不需要更改 alsa.conf 的文件权限

      在我的情况下,这仍然抛出了以下 ALSA 错误:

      • ALSA lib pcm_route.c:867:(find_matching_chmap) 找不到匹配的通道映射
      • ALSA lib pcm_route.c:867:(find_matching_chmap) 找不到匹配的通道映射
      • ALSA lib pcm_route.c:867:(find_matching_chmap) 找不到匹配的通道映射
      • ALSA lib pcm_route.c:867:(find_matching_chmap) 找不到匹配的频道图

      【讨论】:

        【解决方案8】:

        我也遇到了同样的问题。

        只需在命令末尾添加2>/dev/null 即可解决我的问题。我只是想抑制错误消息,它成功了。

        例如: python marvin.py 2>/dev/null

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-16
          • 2022-11-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-03
          相关资源
          最近更新 更多