Python 运行时[WINDOWS]期间sounddevice找不到PortAudio库

Python 运行时[WINDOWS]期间sounddevice找不到PortAudio库,python,portaudio,python-sounddevice,Python,Portaudio,Python Sounddevice,问题: 类似于,在使用pyinstaller打包我的应用程序并执行.exe后,我遇到了一个OSError:PortAudio库找不到。(注意,通过shell运行未打包的应用程序时,我不会遇到任何问题。这仅在使用pyinstaller打包时发生) 虽然通过软件包管理器安装portaudio似乎适用于Linux,但这似乎不是Windows的一个选项,因为“如果您使用Mac OS X或Windows,库将使用pip自动安装”和执行pip搜索portaudio只返回包装器 问题 我需要做什么才能使sou

问题: 类似于,在使用
pyinstaller
打包我的应用程序并执行
.exe
后,我遇到了一个
OSError:PortAudio库找不到
。(注意,通过shell运行未打包的应用程序时,我不会遇到任何问题。这仅在使用pyinstaller打包时发生)

虽然通过软件包管理器安装
portaudio
似乎适用于Linux,但这似乎不是Windows的一个选项,因为“如果您使用Mac OS X或Windows,库将使用pip自动安装”和执行
pip搜索portaudio
只返回包装器

问题 我需要做什么才能使
sounddevice
在我的Windows环境中工作? 为什么它在我的shell中工作,但在打包应用程序后却不工作

完全错误:

(venv) λ my-app.exe
Traceback (most recent call last):
  File "site-packages\sounddevice.py", line 71, in <module>
OSError: PortAudio library not found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "point-of-service-recorder.py", line 11, in <module>
    import sounddevice as sd
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "c:\path\to\my\app\venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages\sounddevice.py", line 83, in <module>
OSError: cannot load library 'C:\Users\TYLER~1.HIT\AppData\Local\Temp\_MEI250242\_sounddevice_data\portaudio-binaries\libportaudio32bit.dll': error 0x7e
[23156] Failed to execute script point-of-service-recorder
已安装的软件包

  • 请注意,
    cffi
    sounddevice
    setuptools
    均按照要求提供
    portaudio
    未列出,但我假设它包含在
    sounddevice
    中,就像文档中所说的(?)

对此有些尴尬,但我没有在构建中包含所需的port audio.dll。将它们复制到
env\site包中
并更新
sounddevice.py
以指向正确的
.dll
对我有效


编辑

预构建的DLL可在以下位置找到:

我将它们添加到
/bin
目录,并更新了
sounddevice.py
以使用它们(下面的代码)


这是我从v0.3.13更新的
sounddevice.py
(手动更改标记为#!)


设置我的开发环境时,我运行此bat脚本以使用自定义脚本更新虚拟环境中的默认
sounddevice.py

echo Updating sounddevice.py ...
copy .\sounddevice.py .\venv\Lib\site-packages\sounddevice.py /y
copy .\libportaudio32bit.dll .\venv\Lib\site-packages\libportaudio32bit.dll /y
copy .\libportaudio64bit.dll .\venv\Lib\site-packages\libportaudio64bit.dll /y



提示:请确保锁定sounddevice版本(例如在
requirements.txt中),以便将来的版本不会破坏此黑客行为我将libportaudio32bit.dll打包到我的exe文件中,并删除了以下代码:

# import _sounddevice_data
# _libname = _os.path.join(
#     next(iter(_sounddevice_data.__path__)), 'portaudio-binaries', _libname)
_lib = _ffi.dlopen(_libname)

在sounddevice.py中,它现在正在工作。

我遇到了这个问题。请详细说明您在哪里找到要复制到
env\site packages
文件夹中的.dll,以及您如何准确更新
sounddevice.py
以指向
.dll
,我们将不胜感激。我看到过其他类似的问题没有解决。你从哪里得到的.dll,你是如何将它打包到exe中的?非常感谢您的进一步阐述。
import atexit as _atexit
import os as _os
import platform as _platform
import sys as _sys
from ctypes.util import find_library as _find_library
from _sounddevice import ffi as _ffi


#! built path to my dlls (in my `bin` dir)
#! use _platform.architecture to infer whether to use 32 or 64-bit dll
try:
    _libname = 'libportaudio' + _platform.architecture()[0] + '.dll'
    _libname = _os.path.join('bin', _libname)
    _lib = _ffi.dlopen(_libname)
except OSError:
    if _platform.system() == 'Windows':  #! use Windows, not default 'Darwin'
        _libname = 'libportaudio' + _platform.architecture()[0] + '.dll'
    else:
        #! custom error
        raise OSError('PortAudio library not found! Make sure the system is Windows 64 or 32 bit and you have the '
                      'correct libportaudio dll saved in  site-packages')

#! keep rest the same
echo Updating sounddevice.py ...
copy .\sounddevice.py .\venv\Lib\site-packages\sounddevice.py /y
copy .\libportaudio32bit.dll .\venv\Lib\site-packages\libportaudio32bit.dll /y
copy .\libportaudio64bit.dll .\venv\Lib\site-packages\libportaudio64bit.dll /y

# import _sounddevice_data
# _libname = _os.path.join(
#     next(iter(_sounddevice_data.__path__)), 'portaudio-binaries', _libname)
_lib = _ffi.dlopen(_libname)