Playing songs one by one in a random row

Hi everyone.

I have about 15 .ogg typed - song files for my game. These are all placed in a folder called ’ songs’. I need a script that has connections to all these songs as paths and can play 1 by one randomly, after the previous one just ends. It is perfect also if they have a little bit fading phase between each other.

value SONG should be then an element from a list that is randomly picked… I dont know how to do this, could anyone help me?


import bge
import aud




musics="songs/"
beatmaps="beatmaps/"
cdlabels="labels/"

device = aud.device()

factory = aud.Factory(bge.logic.expandPath("//"+musics+SONG))
factory_buffered = aud.Factory.buffer(factory)
handle = device.play(factory_buffered)



player.py


import os
import bge
import random

PROPERTY_MUSIC_FOLDER = "folder"

INTERNAL_PROPERTY_REMAINING_SONGS = "_remainingSongs"

def restartFolder():
    playListManager = bge.logic.getCurrentController().owner
    
    folder = playListManager[PROPERTY_MUSIC_FOLDER]
    path = bge.logic.expandPath("C:/MyInstall/blender-2.73-windows32")
    
    fileNames = findFileNames(path)
    random.shuffle(fileNames)
    
    playListManager[INTERNAL_PROPERTY_REMAINING_SONGS] = fileNames

def playNextSong():
    if not sensorsAllPositive():
        return

    playListManager = bge.logic.getCurrentController().owner
    remainingSongs = playListManager[INTERNAL_PROPERTY_REMAINING_SONGS]
    if remainingSongs:
        play(remainingSongs.pop())
    
def findFileNames(path):
    return[ f for f in os.listdir(path) 
      if os.path.isfile(os.path.join(path,f)) ]

def play(songName):
    print("write your own function to play", songName)    

def sensorsAllPositive():
    for sensor in bge.logic.getCurrentController().sensors:
        if not sensor.positive:
            return False
    return True    

you can call two functions:
-> player.restartFolder which reads the files in the folder and randomizes the filenames
-> player.playNextSong which grabs the next filename from the remaining filenames

Be aware:

  • You need a string property “music” which contains the path to the folder (can be relative to the blend file).
  • You need to call restartFolder before calling playNextSong!
  • The filenames are only filtered to be files. They are not filtered by extention - you need to add that by your own
  • playNextSong calls play(songName) - it just prints a statement. You need to implement the playing by yourself
  • it does not recognize if a song finished -> by yourself
  • to detect if all songs are played use “if remainingSongs:” which checks if the list is not empty

I hope it helps

Hi! Another solution: http://www.mediafire.com/download/ty6l7ap5yq4dzw3/shuffle&fade.rar

(There’s also a fadeout function but I don’t know how to use it (I don’t know if we must know the song duration in seconds to use it))

EDIT: two of the three songs I used are already “faded out” (I think) but I did not use fade out function.

EDIT2: I found a fine library to find mp3 duration, so we can use fadeout function easily: tinytag


It’s just one script so we can easily include it in the .blend file:

thanks monster and youle, i will take a look into these options.