繁体   English   中英

Pyglet 可以读取使用 PyInstaller 创建的 Python Mac 应用程序 (.app) 中的 mp3 文件,但仅当我从命令行运行该应用程序时

[英]Pyglet can read mp3 files in a Python Mac application (.app) created with PyInstaller, but only when I run the application from the command line

我正在使用依赖于pyglet版本 1.5.27 的Python 3.10.8( Miniconda发行版)创建一个程序 我的程序的一个功能涉及使用此 function 将音频文件加载到pyglet中:

pyglet.media.load("{path_to_audio_file}")

最近,我使用 PyInstaller 将程序的源代码打包成一个Windows可执行文件 (.exe) 和一个Mac应用程序 (.app)(尽管我对 Windows版本使用了Auto Py to Exe )。

这是我用来构建程序的Mac版本的PyInstaller命令(将 {path_to_repository} 替换为本地计算机上存储库的位置):

pyinstaller --noconfirm --onedir --windowed --icon "{path_to_repository}/setup_files/mac/file_icon_mac.icns" --add-data "{path_to_repository}/src/classes:classes/" --add-data "{path_to_repository}/src/images:images/" --add-data "{path_to_repository}/messages:messages/"  "{path_to_repository}/src/Time Stamper.py"

Auto Py to Exe生成的Windows命令看起来与上面的命令完全一样,除了......

  • 提供了Windows图标 (.ico) 文件的路径,而不是Mac图标 (.icns) 文件的路径

  • 所有冒号(“:”)都替换为分号(“;”)。

我可以在我的程序的Windows版本以及我的程序的Mac版本上使用pyglet加载和播放 mp3 文件,但是

  • 当我通过双击启动应用程序 (.app) 时, pyglet无法在我的程序的Mac版本上加载 mp3 文件。

  • pyglet只会在我的程序的Mac版本上加载我的 mp3 文件当我...

    • 通过右键单击我的Mac应用程序 (.app),然后选择“显示 Package 内容”并导航到“内容”->“MacOS”,然后双击该文件夹中的 Unix 可执行文件来启动它。

      或者

    • 通过输入以下命令启动我的Mac应用程序 (.app):

       open -n {path_to_my_app} --args -AppCommandLineArg
  • 当我尝试通过简单地双击 .app 文件来启动我的程序的Mac应用程序 (.app) 时,我收到以下错误消息:

     {Traceback (most recent call last): } { File "pyglet/media/codecs/wave.py", line 58, in __init__ } { File "wave.py", line 509, in open } { File "wave.py", line 163, in __init__ } { File "wave.py", line 130, in initfp } {wave.Error: file does not start with RIFF id } { During handling of the above exception, another exception occurred: } {Traceback (most recent call last): } { File "tkinter/__init__.py", line 1921, in __call__ } { File "classes/macros/macros_buttons_file.py", line 107, in button_audio_select_macro self.parent.validate_audio_player() } { File "classes/macros/macros.py", line 229, in validate_audio_player verify_audio_file(self.widgets["entry_audio_path"].get(), self.time_stamper) } { File "classes/macros/macros_helper_methods.py", line 225, in verify_audio_file time_stamper.audio_source = load(file_full_path) } { File "pyglet/media/__init__.py", line 142, in load } { File "pyglet/media/__init__.py", line 132, in load } { File "pyglet/media/codecs/wave.py", line 105, in decode } { File "pyglet/media/codecs/wave.py", line 60, in __init__ } {pyglet.media.codecs.wave.WAVEDecodeException: file does not start with RIFF id }
  • 此外,这些是由PyInstaller生成的警告, PyInstaller将其放置在“build/Time Stamper/warn-Time Stamper.txt”(“Time Stamper”是我的应用程序的名称)中:

     This file lists modules PyInstaller was not able to find. This does not necessarily mean this module is required for running your program. Python and Python 3rd-party packages include a lot of conditional or optional modules. For example the module 'ntpath' only exists on Windows, whereas the module 'posixpath' only exists on Posix systems. Types if import: * top-level: imported at the top-level - look at these first * conditional: imported within an if-statement * delayed: imported within a function * optional: imported within a try-except-statement IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for tracking down the missing module yourself. Thanks. missing module named pep517 - imported by importlib.metadata (delayed) missing module named 'org,python' - imported by copy (optional). xml,sax (delayed. conditional) missing module named org - imported by pickle (optional) missing module named winreg - imported by importlib,_bootstrap_external (conditional), mimetypes (optional). urllib,request (delayed, conditional, optional), platform (delayed, optional) missing module named nt - imported by os (delayed, conditional, optional), ntpath (optional), shutil (conditional). importlib,_bootstrap_external (conditional), ctypes (delayed. conditional) missing module named _frozen_importlib_external - imported by importlib,_bootstrap (delayed), importlib (optional). importlib,abc (optional) excluded module named _frozen_importlib - imported by importlib (optional). importlib,abc (optional) missing module named _winapi - imported by encodings (delayed, conditional, optional), ntpath (optional), subprocess (optional), mimetypes (optional) missing module named msvcrt - imported by subprocess (optional), getpass (optional). pyglet.extlibs,png (delayed. conditional) missing module named pyogg - imported by pyglet.media.codecs.pyogg (top-level) missing module named PIL - imported by pyglet.image.codecs.pil (optional) missing module named Image - imported by pyglet.image.codecs,pil (optional) missing module named vms_lib - imported by platform (delayed. optional) missing module named 'java,lang' - imported by platform (delayed, optional). xml.sax,_exceptions (conditional) missing module named java - imported by platform (delayed) missing module named _winreg - imported by platform (delayed. optional) missing module named pyglet.window.BaseWindow - imported by pyglet,window (top-level). pyglet.window,headless (top-level). pyglet.window,cocoa (top-level). pyglet.window,win32 (top-level). pyglet.window.xlib (top-level) missing module named 'gi.repository' - imported by pyglet.media.codecs.gstreamer (optional) missing module named gi - imported by pyglet.media.codecs.gstreamer (optional)

我知道pyglet可以更好地处理 wav 文件,但我发现pyglet可以在任何情况下读取我的 mp3 文件很奇怪,除了我Mac上的这个非常特殊的情况,所以如果可能的话,我真的很想让它也在那里工作. 此外,我在配备 1.7 GHz 双核英特尔酷睿 i5 处理器的 11 英寸 2012 年中期MacBook Air上运行macOS Catalina 10.15.7。

更新:

我一直在对此进行更多试验,我相信我已经确定了问题所在。 要读取 mp3 文件, pyglet需要ffmpeg 当我使用以下命令安装pyglet时, ffmpeg依赖项已自动安装到我的计算机上:

conda install -c conda-forge pyglet

当我只是从命令行运行我的Mac应用程序 (.app) 时:

  • 我的应用程序 (.app) 默认使用我系统的默认Python解释器(即我的基本miniconda环境),因此我的应用程序拥有我使用“conda/pip install”命令安装的所有Python包供其使用。
    • 这意味着,当我从命令行运行我的应用程序 (.app) 时,我的计算机能够找到pyglet以及与pyglet一起安装的ffmpeg依赖项(允许我的应用程序读取 mp3 文件)。

但是,当我通过双击PyInstaller生成的应用程序 (.app) 运行我的Mac应用程序时:

  • 我的计算机依赖于PyInstaller应用程序 (.app) 包中包含的包。
    • 由于PyInstaller似乎检测到pyglet是我的应用程序 (.app) 运行所必需的,因此它在最终应用程序 (.app) 包中包含pyglet ,因此我怀疑PyInstaller会自动在此应用程序 (.app) 包中包含ffmpeg同样(因为当我运行上述“conda install”命令时, ffmpeg作为依赖项与pyglet一起自动安装)。 然而,情况似乎并非如此。

我几乎可以肯定PyInstaller没有在我的Mac应用程序 (.app) 中包含ffmpeg ,因为在调试我的代码时,我发现以下语句......

pyglet.media.have_ffmpeg()

当我从命令行运行我的应用程序 (.app) 时评估为True ,但当我双击PyInstaller生成的应用程序 (.app) 时评估为False

所以现在,我想弄清楚如何让PyInstaller在我的Mac应用程序 (.app) 中包含ffmpeg ,这样pyglet就可以检测到ffmpeg在那里(我相信,这将允许pyglet使用ffmpeg来能够阅读 mp3 文件),但我终究无法弄清楚如何做到这一点。

为了尝试让PyInstaller在我的Mac应用程序 (.app) 中包含ffmpeg ,我尝试将以下 arguments 的不同排列添加到我的pyinstaller命令中:

--add-binary "/opt/miniconda3/bin/ffmpeg:bin/"
--add-binary "/opt/miniconda3/bin/ffmpeg:ffmpeg/"
--add-data "/opt/miniconda3/lib/python3.10/site-packages/ffmpeg"
--collect-all pyglet
--collect-all ffmpeg
--collect-all ffmpeg-python

添加时,这些 arguments 似乎都没有使PyInstaller在我的应用程序 (.app) 中包含ffmpeg ,或者至少,如果包含ffmpeg (我不认为它是,但我不确定),然后这些 arguments 不允许pyglet检测到它。

此外,最后两个 arguments 被PyInstaller完全忽略,因为它表示没有名称为ffmpegffmpeg-python的包。 我什至使用以下命令使用conda安装了独立的ffmpeg包(然后再次尝试运行PyInstaller命令):

conda install -c conda-forge ffmpeg
conda install -c conda-forge ffmpeg-python

安装这些包然后再次运行PyInstaller 会产生同样的问题(即PyInstaller没有检测到任何名称为ffmpegffmpeg-python的包,因此这些包被忽略并且不包含在 .app 包中)。

因此,根据我迄今为止对我的问题的完整理解,似乎我需要找到一种方法将 package ffmpeg正确地放入我的应用程序 (.app) 中,以便pyglet可以与之通信。 有任何想法吗?

你是对的,Mac 在 Pyglet 中默认不支持 MP3(这将在即将推出的 2.x 版本中添加并可能向后移植到 1.5)并且需要 FFmpeg。

Pyglet 在os.environ["DYLD_LIBRARY_PATH"]中查找 ffmpeg 的 dylib 文件。 您还可以尝试使用pyglet.options["search_local_libs"] = True ,它将在您的脚本目录中搜索名为lib的文件夹以查找这些 lib 文件。

以下是有关 ffmpeg 安装的一些信息: https://pyglet.readthedocs.io/en/latest/programming_guide/media.html#ffmpeg-installation

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM