How to pause and resume sound in bge using aud

I have this script I am using to play sound from a video, however I fear I am not experienced enough to figure out how to set up a pause/play system into it any ideas?

(more info: I am calling the script from a module, thats why I have ‘def play_m()’)

import bge
import aud
cont = bge.logic.getCurrentController()
own = cont.owner
moviename = str(own[‘MovieName’])
mpitch = int(own[‘MoviePitch’])
original_sound = aud.Factory.file(bge.logic.expandPath("//…\Movie\")+moviename)
quite_sound = original_sound.volume(mpitch)

def play_m():
print(moviename)
handle = aud.device().play(quite_sound)
play_m()

Preformated text tags improve readability of code on the forums.

import bge
import aud
cont = bge.logic.getCurrentController()
own = cont.owner
moviename = str(own[‘MovieName’])
mpitch = int(own[‘MoviePitch’])
original_sound = aud.Factory.file(bge.logic.expandPath("//…\Movie\")+moviename)
quite_sound = original_sound.volume(mpitch)
 
def play_m():
    print(moviename)
    handle = aud.device().play(quite_sound)
play_m()

I’ll just mention that the reason it looks odd at the end is because your path on line 7 is not very compliant - expandPath: // = blend file directory; ../ = up one; / = directory separator. bge.logic.expandPath("//../Movie/"+moviename)

To pause, resume or stop playback you can use the aud.Handle methods of the same names: handle.pause(), handle.resume(), and handle.stop() The problem is you don’t have continuous access to the handle. The file is still there but you lose your handle as soon as the function play_m() falls off the end. The most simple way to keep that handle is by making it a property of the owner object:

owner['handle'] = aud.device().play(quite_sound)

Now you can access that from other functions you create such as “pause_m()” or “resume_m()” or etc with:

owner['handle'].pause() #.resume() or .stop()

Hope this helps get you started.

here is a fully working class, you can plug the stuff you need from it or use it as is.

import aud
import os
import random
import time

__all__ = ["Audio"]

class Audio:
    
    def __init__(self,**kw):        
        self.filename = None
        self.path=""
        self.folder=""
        
        for arg in kw:
            if arg in vars(self):
                self[arg] = kw[arg]
                
        self.song = ""        
        self.device = aud.device()
        self.handle = None                
        self.playlist = []                   
        self.sound = None   
        
        random.seed(time.time())
        
        if self.path:
            self.path = os.path.join(self.path)
        else:
            self.path = os.path.join(os.getcwd())
        
        if self.filename:
            self.load(self.filename)


    def __getitem__(self, key):
        return getattr(self, key)
    
    def __setitem__(self, key, value):
        setattr(self, key, value)
        
    def setPath(self,path):
        self.path = path
        
    def setFolder(self,folder):
        self.folder = folder
        
    def load(self,filename):
        
        if filename:
            self.filename = filename
            filename = os.path.join(self.path,self.folder,self.filename) 

            self.sound = aud.Factory(filename)

            
    def play(self):
        
        if self.sound:
            try:
                self.handle = self.device.play(self.sound)
            except:
                pass

    def loadplaylist(self):
        for root, directories, filenames in os.walk(self.path):
            for filename in filenames: 
                if ".flac" in filename or ".mp3" in filename:
                    self.playlist.append(os.path.join(root,filename))
        return self.playlist
        
    def playrandom(self):
        self.stop()
        
        if self.playlist:
            random.shuffle(self.playlist)
            return self.getnextsong()
        else:
            self.loadplaylist()
            random.shuffle(self.playlist)
            
            return self.getnextsong()

        return ""
    
    def getnextsong(self):
        self.stop()
        self.song = self.playlist.pop()
        self.load(self.song)
        self.handle = self.device.play(self.sound)
        return self.song
        
    def stop(self):
        if self.handle:
            self.handle.stop()
          
    def limit(self,start,end):
        self.sound = self.sound.limit(start,end)
            
    def pause(self):
        if self.handle:
            self.handle.pause()

    def resume(self):
        if self.handle:
            self.handle.resume()
            
    def isplaying(self):
        if self.handle:
            return self.handle.status
        else:
            return False
    
    def volume(self,setvolume):
        if self.handle:
            self.handle.volume = setvolume
            
    def loop(self,loops=0):
        if self.handle:
            self.handle.loop_count = loops
            
    def pitch(self,setpich):
        if self.handle:
            self.handle.pitch = setpich    
            
1 Like

Thanks a bunch guys! My problems are solved.

Here is the new code:

import bge
import aud
cont = bge.logic.getCurrentController()
own = cont.owner
moviename = str(own['MovieName'])
mpitch = int(own['MoviePitch'])
original_sound = aud.Factory.file(bge.logic.expandPath("//..\..\Movie\\")+moviename)
quite_sound = original_sound.volume(mpitch)
if own['MovieSound']==True:
    if own['ispaused']==False:
        if own['handle_m']=="":
            print(moviename)
            own['handle_m'] = aud.device().play(quite_sound)
        else:
            own['handle_m'].resume()
    elif own['ispaused']==True:
        own['handle_m'].pause()

I know there is a bit more stuff there but if any one wants this code in the future its here.
sodsm_live, the path is a matter of personal preference, that works too, however I find changing the direction of the slash to be more true to my roots in system administration so its how I write them (easier to understand for me) thanks anyways.

In regards to your ‘isplaying’ method, contrary to the documentation, Handle.status returns True if the sound is playing or paused but doesn’t distinguish between them. I check if it’s playing or paused by what Handle.resume() returns(after checking if Handle is valid and Handle.status returns True of course). If it returns True, you know it was paused and can immediately re-pause it to maintain the state. If it returns False, you know it was actually playing.

not important for what i use it for.