4

So, I'm working on a little project for myself, using pygame and tkinter to build an mp3 player. Everything works when running the program using visual studio, but when I turned the program to an .exe file using pyinstaller and tried to run in, the following appeared:
pygame.mixer.load(song)
pygame.error
Failed to execute script

I've tried everything, but it keeps telling me the same. Here you can see how I call the song:

pygame.init()
pygame.mixer.init()

song = path + '\music\\' + selected_song
pygame.mixer.music.load(song)

Being path + '\music\\' , the directory where the songs are. And slected_song the name of the song + '.mp3'.

Red
  • 26,798
  • 7
  • 36
  • 58
  • 1
    `os.path.join(path, "music", selected_song)` – furas Jul 16 '20 at 14:20
  • is this full error which you get ? always put full error message (starting at word "Traceback") in question (not comment) as text (not screenshot). There are other useful information. – furas Jul 16 '20 at 14:21
  • 1
    Python wasn't created to build .exe files and programs like `pyinstaller` may have problem to find all modules and C/C++ libraries needed to work and you may have to add them manually - for example PyGame depends on C/C++ library `SDL`. Search more info on PyInstaller page - ie. in FAQ. BTW: If you don't get more error message then you could use `print()` to see values in variables. Maybe your `path` is not correct and it has problem to load it. System may run it in different folder then you expect and then `path` may be incorrect - especially if it is relative path. – furas Jul 16 '20 at 14:24
  • What is your python/pygame version? – kaktus_car Jul 16 '20 at 14:35
  • @furas I've printed the paths and they are all fine. Maybe it's the pyinstaller problem you told me about. I'm gonna look that up. Thank you! – Miguel Carvalho Jul 16 '20 at 14:37
  • @kaktus_car Python 3.8 and pygame 1.9.6 I believe – Miguel Carvalho Jul 16 '20 at 14:42
  • Update to 2.0.0.dev6 or newer, I also had issues with python 3.8 and pygame 1.9.6 when using pyinstaller. I think it is worth a try – kaktus_car Jul 16 '20 at 14:45
  • PyInstaller doc: [When Things Go Wrong](https://pyinstaller.readthedocs.io/en/stable/when-things-go-wrong.html) and [Using Spec Files](https://pyinstaller.readthedocs.io/en/stable/spec-files.html) – furas Jul 16 '20 at 14:51
  • 1
    What is the value for "path" ? – Eric Mathieu Jul 16 '20 at 16:52

3 Answers3

2

You need double backslashes:

From:

song = path + '\music\\' + selected_song

To:

song = path + '\\music\\' + selected_song

Or:

song = f"{path}\\{music}\\{selected_song}"
Red
  • 26,798
  • 7
  • 36
  • 58
  • @MiguelCarvalho Have a look [here](https://stackoverflow.com/q/40716346/13552470). – Red Jul 16 '20 at 14:22
1

As I mentioned it comment update pygame to version 2.0.0.dev6 or newer, and another possible issue is when making .exe pyinstaller puts it in the dist folder. So if you haven't moved it from that folder, paths are incorrect and the files couldn't be located, hence the error.

kaktus_car
  • 986
  • 2
  • 11
  • 19
0

When python programs are packaged up with pyInstaller, CXFreeze, etc. The first part of the execution is unpacking everything into a temporary location. Then the executable may not be run from that same directory either.

So it's important that the python program itself determines the current working directory and finds where its resource files are. Images, sounds etc. will no longer be at "./music" or "./assets/images", it's probably something more like "/tmp/cxunpack.125423/assets/sounds/".

The script needs to work out the location it is running from:

import sys
import os.path

if getattr(sys, 'frozen', False):  # Is it CXFreeze frozen
    EXE_LOCATION = os.path.dirname( sys.executable ) 
else:
    EXE_LOCATION = os.path.dirname( os.path.realpath( __file__ ) ) 

And then use this in combination with os.path.join() to determine the correct path to the needed file:

song_filename = os.path.join( EXE_LOCATION, "music", "first.mp3" )
pygame.mixer.music.load( song_filename )

Using os.path.join() is important because it makes your program more platform independent, and handles a few little problems with joining paths automatically.

Kingsley
  • 14,398
  • 5
  • 31
  • 53