[solved] How to address music files in a p3d file?

I’d like to include my music into a p3d file, and play those files when running the p3d file. But I don’t know how to do so.

I couldn’t find anything about it in the manual.

I’ve tried adding the files in a dependency package, but that didn’t seem to work.

I’ve also tried to add the extension ( -n ogg ) as an argument to packp3d, but I couldn’t figure out how to address those files. These files are originally under client/art/music/ .

Why is it any different than loading the music files in a development environment, e.g. with loader.loadMusic()?


I suppose it’s related then to the way I select which file is played (a random file in the music directory is played):

from os import listdir
from random import choice

from pandac.PandaModules import AudioSound

__music = None
__music_path = u'client/art/music'

def get_music_status():

    return (__music !=  None) and (__music.status() ==  AudioSound.PLAYING)

def toggle_music():

    global __music

    if get_music_status():
        # in the line below the error occurs
        files = [file_ for file_ in listdir(u'%s/' % __music_path) if '.ogg' in file_]

        if len(files) ==  0:
            raise IOError, 'No music files found.'
            file_ = choice(files)
            __music = loader.loadSfx(u'%s/%s' % (__music_path, file_))
            __music.setLoopCount(0) # Loop forever.
            print u'playing music: %s' % file_

The ‘listdir’ function fails, because the path ‘start/client/art/music/’ doesn’t exist.

Is there something similar to the ‘listdir’ function that wouldn’t cause this error?

The os.listdir() function should work, but note that the contents of your p3d file won’t be found within the current directory (in 1.7.0–we’ll change this in 1.7.1).

This means that you should look in base.appRunner.multifileRoot + ‘/client/art/music’ instead of in ‘client/art/music’.


Ok, thanks a lot!

“won’t be found within the current directory (in 1.7.0–we’ll change this in 1.7.1).”

So you are putting (vfs mounting) all packages in the current dir? Thats much nicer. Right now I run a script that finds all my packages at start time and mounts them properly in the current directory.

No, just the p3d file.

We can’t mount all the packages onto the same mount point, because the packages may have a real-file component: some files in a package (like dll files) have to be physically extracted to disk. This means that each package has to have its own, separate directory (in which we can extract these files); and it also follows that the package has to mounted to its own directory. Which means that the packages have to live elsewhere than in the current directory.

Also, I’m not sure that there wouldn’t be filename collisions between different packages. Mounting them separately helps resolve that.

If you know that your particular packages have no real-file components, and that they have no filename collisions, you can safely mount them all to the current directory. But I don’t see how we can do that in general.