-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pygame.mixer can't load sound when frozen by Pyinstaller #1514
Comments
Thank you for reporting this, and for the detailed test case. I have recently looked into the file loading code. It uses the SDL2 RWops. I looked at the SDL2 file loading code too, and it sometimes does "clever" platform-specific things with paths. So possibly, this also depends on the SDL2 version, or it only happens with "\" path separators. Maybe not. Dear contributors/maintainers: |
I tested on pygame 2 dev 6, python 3.7.5, and pyinstaller 3.5. Line of code with error: Error msg: |
Yeah. I ran your code on my machine. It obviously doesn't work on any Unix-like system. What if you change the line to I also looked at your spec file. You don't even package the assets into a self-extracting .exe, something that is normally a source of problems. |
can you try and paste the output of this:
If it fails, can you try again with the different successive |
When run from source: (worked with every sound= line)
When run from executable: (output read by turning the console flag of the spec file to True)
And for the other sound lines: (not including the version printouts)
Yeah I wasn't worrying about cross-compatibility in this, but in my actual project I have a handle_path method that converts all the paths to absolute paths that the operating system will like. I've heard about packaging the dependencies with pyinstaller, but I've preferred bundling them in next to the exe myself. That way they are visible and editable to end users. I've had problems with this, mainly on mac, which runs unknown exes in a weird secure folder somewhere away from all its assets, but my handle_path method has been able to handle them. Anyways the weird thing to me is that this works in pygame 1.9.6 and not pygame 2. |
When you corrected the path format were you able to reproduce this on Linux? |
I was not able to reproduce this on Linux. I have pyinstaller installed twice. One in my normal FS and once in a steam-runtime chroot. BUT: I have encountered a similar bug when using python-for-android to bundle pygame games (not production ready yet, but file loading works now). It will take a while to debug this, but I think I know where to look. Or maybe this is a bug in PyInstaller. I don't know yet. As PyInstaller is one of the few well-maintained tools that can be used to deploy PyGame games (the others being cx_freeze, and pynsist) it's important that we get this to work, even if it's a bug in PyInstaller. (My money is on SDL2 changing behaviour compared to SDL1.2, but I don't want to point fingers and assign blame here. This bug is just tricky to chase down!) |
I had a similar error when trying to freeze my games using pyinstaller, python 3.7, and pygame2. I did not have this problem with python2.7 and pygame1.96, or with python3.7 and pygame2 on linux. It was not a mixer or SDL problem, but pyinstaller that failed to include all of the necessary pygame or sdl2 components. After I copied my pygame folder into the the dist folder the game ran without error. Not sure if this is the same problem this user had but it might be. |
Pyinstaller has a problem with packaging up the pygame project. You have to copy all the libxxxx.dll (especially "libogg-0.dll") from pygame files and paste them into your "main" file. This will solve the problem. |
I think I fixed it! I changed the pygame hook in my local pyinstaller to this:
I've tested that this resolves my issue on windows in pygame 2.0.0.dev10. I've also tested it in pygame 1.9.6 and in onefile mode, and those both work as well. Because it is using @illume Do you think this is ready to submit to pyinstaller? |
Hi, cool! Yeah, submit a PR if it works :) No idea why 2.0.dev6+ requires that though. I wonder if any pygame 2 versions before dev6 work (dev1-dev5)? If so, that could help us fix the problem in pygame itself, rather than have to wait for the PR to be merged and a new release made. Because the problem seems to have started between pygame 1.9.6 and 2.0.0.dev6. I guess people can use the hook you made before/if a new pyinstaller is released :) There's a command line option to tell it to look in a particular folder right? I can't seem to find a way for pygame itself to provide the hook. |
I guess the main thing to check would be whether this works to create frozen executable code on macs and linux with a test project. I'm assuming that you are on Windows due to the mention of .dlls and .exe files. I don't know what the standards are for submitting pull requests to PyInstaller but I expect that kind of testing is what I would want to know if I was in charge over there. From my eyeballing of your changes and a look at other hook files in the PyInstaller repo, what you've done doesn't seem wildly out of step with other project's hook files. If it makes the situation better on windows (and it sounds like it does) and doesn't make it worse for mac and linux users then I have no objection. Heck knows I've answered enough pygame on PyInstaller questions so anything to reduce those a little would be welcome. |
I tested it on pygame 2.0.0.dev1 and the problem started then. Maybe it's something inside SDL2 making them not "included/imported" in PyInstaller's view. These are the DLLs that are present in the project when built with pygame 1.9.6 but not with pygame 2:
I tested my solution on mac and it didn't affect anything. But to avoid any problems on other operating systems I'll make my solution test whether it's on windows first. There's a command line to add local hooks, and there's an option in spec files for it as well. I wish modules could embed their hooks in their folders. Edit: looks like they're going this direction Final hook solution:
|
Looks good to me 👍 Hmm... if the next release of PyInstaller will allow package hooks, and this hook won't make it into PyInstaller until the next release anyway - should we just hold fire on this and incorporate it into pygame when the new system is ready? Though even if we went that route, if they are keeping the existing hooks in the Pyinstaller project anyway we'd probably want to replace that one with one that works on windows anyway, just in case someone uses an old version of pygame 2 with a newer version of PyInstaller. Perhaps @illume might be against adding PyInstaller specific config files into the repo on principle - I know they prefer CxFreeze over PyInstaller for several reasons. Anyway if we do go the 'Pyinstaller hook in pygame repo route' it at least looks like the hooks can be tucked away neatly via setup.cfg. See this example project: And the documentation from that pull request: Looks like that example project also has an example of testing PyInstaller freezing automatically on CI which is vaguely interesting too: |
Thanks for trying it with dev-1 :)
Not near a computer atm, but I wonder if all the pygame 2 dll files are
added to package data in the setup.py?
…On Friday, June 26, 2020, Starbuck5 ***@***.***> wrote:
I tested it on pygame 2.0.0.dev1 and the problem started then. Maybe it's
something inside SDL2 making them not "included/imported" in PyInstaller's
view.
These are the DLLs that are present in the project when built with pygame
1.9.6 but not with pygame 2:
libogg-0.dll
libmpg123-0.dll
libvorbis-0.dll
libvorbisfile-3.dll
libtiff-5.dll
libwebp-5.dill
libgcc-5-5jlj1.dll
I tested my solution on mac and it didn't affect anything. But to avoid
any problems on other operating systems I'll make my solution test whether
it's on windows first.
There's a command line to add local hooks, and there's an option in spec
files for it as well.
I wish modules could embed their hooks in their folders.
Final hook solution:
"""
binaries hook for pygame seems to be required for pygame 2.0.
Otherwise some essential DLLs will not be transfered to the exe.
"""
import platform
if platform.system() == "Windows":
from PyInstaller.utils.hooks import collect_dynamic_libs
pre_binaries = collect_dynamic_libs('pygame')
binaries = []
for b in pre_binaries:
binary, location = b
# settles all the DLLs into the top level folder, which prevents duplication
# with the DLLs already being put there.
binaries.append((binary, "."))
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1514 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAACKRKZOKTKLUFL7QPDM3DRYPSWBANCNFSM4JO5XPXA>
.
|
I'm not against the pyinstaller hook, and if it works... great. |
Internal pyinstaller hook (Fixes #1514)
The PR was merged in. Leaving this open until someone can confirm the next release works with pyinstaller on windows. |
Ankith confirmed that the hook works on discord, so I'll close this. |
This works for me using pyinstaller and pygame.mixer. ` os.chdir(os.path.dirname(os.path.abspath(file))) |
Tested on windows 10.
I tested with pygame 1.9.6 and pygame 2, and it worked in pygame 1.9.6.
Attached is my test code, compiled into executables with pygame 1.9.6 and pygame 2.
mixer_load_test.zip
Related Docs: https://www.pygame.org/docs/ref/mixer.html#pygame.mixer.Sound
Remaining work to do
The text was updated successfully, but these errors were encountered: