![]() |
Pyglet Media: unjustifiable memory usage - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Pyglet Media: unjustifiable memory usage (/thread-4474.html) |
Pyglet Media: unjustifiable memory usage - hbknjr - Aug-19-2017 Hi, I was recommended Pyglet for creating music player Here. I encountered an issue of high memory usage while playing mp3 files. PROBLEM: I created a player object and loaded/queued some mp3s but each time when I use the next_source method to play the next queued mp3 it takes around 50-80mb of additional RAM. I tried to use memory_profiler but in vain. Here are the steps to recreate the issue: 1: Run below code in a directory with few mp3 files, and plz make sure to fulfill requirements. #requirements #Pyglet #http://avbin.github.io/AVbin/Download.html #https://pypi.python.org/pypi/memory_profiler import os import fnmatch from memory_profiler import profile from pyglet.media import * from pyglet.media.avbin import AVbinException class MusicPlayerCore(): def __init__(self): self.player = Player() self.loadsource() #loading all mp3 in player @profile def loadsource(self): songpathlist = self.recur_searchindir() for song in songpathlist: try: source = load(song) self.player.queue(source) except AVbinException: pass @profile def play(self): self.player.play() def pause(self): self.player.pause() @profile def next(self): self.player.next_source() #Find all mp3 in current directory of script def recur_searchindir(self): directory = os.path.dirname(os.path.realpath(__file__)) songpathlist = [] for root, dirnames, filenames in os.walk(directory): for filename in fnmatch.filter(filenames, '*.mp3'): songpathlist.append(os.path.join(root, filename)) return songpathlist def main(): player = MusicPlayerCore() while 1: print("1-Play \n 2-Pause \n 3- Play Next\n 4- Exit") ch = int(input("Enter choice:")) if ch == 1: player.play() elif ch == 2: player.pause() elif ch == 3: player.next() elif ch == 4: break else: print("Wrong choice") if __name__ == "__main__": main()Here's an alternate way I tried by deleting the player object, calling gc, and recreating it but no success. #requirements #Pyglet #http://avbin.github.io/AVbin/Download.html #https://pypi.python.org/pypi/memory_profiler import os import fnmatch import gc from memory_profiler import profile from pyglet.media import * from pyglet.media.avbin import AVbinException class MusicPlayerCore(): def __init__(self, songlist): self.songlist = songlist #list of path of all songs in dir self.player = Player() #pyglet player object self.songnav = NextandPrev(songlist) self.currentsong = songlist[0] # path of current song | initially first song self.loadsource() # load currentsong #loading current song in player @profile def loadsource(self): try: source = load(self.currentsong) self.player.queue(source) except AVbinException: self.songnavupdate_next() #updating previous and current song path @profile def songnavupdate_next(self): if self.songnav.n_song != None: self.makenewplayer() # create new player object self.currentsong = self.songnav.n_song self.songnav.remake_list(self.currentsong) self.loadsource() #updating previous and current song path @profile def songnavupdate_prev(self): if self.songnav.p_song !=None: self.makenewplayer() # create new player object self.currentsong = self.songnav.p_song self.songnav.remake_list(self.currentsong) self.loadsource() #Make a new Player object, deleting previous one @profile def makenewplayer(self): '''memory_profiler shows no change in memory usage here''' self.player.delete() #deleting current player object #del self.player gc.collect() #explicitly calling gc.collect to remove out of scope player object self.player = Player() #new player object @profile def play(self): self.player.play() def pause(self): self.player.pause() @profile def play_next(self): self.songnavupdate_next() self.player.play() @profile def play_prev(self): self.songnavupdate_prev() self.player.play() class NextandPrev(): def __init__(self, songlist): self.songlist = songlist self.n_song = songlist[1] self.p_song = None def remake_list(self, current_song): index = self.songlist.index(current_song) try: self.n_song = self.songlist[index + 1] except IndexError: self.n_song = None try: self.p_song = self.songlist[index - 1] except IndexError: self.p_song = None #Find all mp3 in current directory of script def recur_searchindir(): directory = os.path.dirname(os.path.realpath(__file__)) songpathlist = [] for root, dirnames, filenames in os.walk(directory): for filename in fnmatch.filter(filenames, '*.mp3'): songpathlist.append(os.path.join(root, filename)) return songpathlist def main(): songpathlist = recur_searchindir() player = MusicPlayerCore(songpathlist) while 1: print("1-Play \n 2-Pause \n 3- Play Next\n 4- Previous \n 5- Exit") ch = int(input("Enter choice:")) if ch == 1: player.play() elif ch == 2: player.pause() elif ch == 3: player.play_next() elif ch == 4: player.play_prev() elif ch == 5: break else: print("Wrong choice") if __name__ == "__main__": main()I also tried to understand the pyglet code but it is too optimized for readability and I'm not pro enough. RE: Pyglet Media: unjustifiable memory usage - Larz60+ - Aug-19-2017 The docs advise using: music = pyglet.resource.media('music.mp3') music.play()see: http://pythonhosted.org/pyglet/programming_guide/playing_sounds_and_music.html I am not familiar with this package, but will show this anyway RE: Pyglet Media: unjustifiable memory usage - hbknjr - Aug-19-2017 (Aug-19-2017, 04:04 PM)Larz60+ Wrote: The docs advise using: pyglet.resource.media and pyglet.media.load[I used] both are same. [inline] pyglet.resource.media locates the sound file in the application's directory (not the working directory). If you know the actual filesystem path (either relative or absolute), use pyglet.media.load.[/inline] They just load the source and return source object which is passed to the player. I think the problem is with player object, but then my alternate method didn't work either. RE: Pyglet Media: unjustifiable memory usage - snippsat - Aug-19-2017 (Aug-19-2017, 02:54 PM)hbknjr Wrote: PROBLEM: I created a player object and loaded/queued some mp3s but each time when I use the next_source method to play the next queued mp3 it takes around 50-80mb of additional RAM.Pyglet use Python garbage collector to release stuff from memory. There is a Player.delete() method that release resources immediately.They doc for this is here. RE: Pyglet Media: unjustifiable memory usage - hbknjr - Aug-20-2017 (Aug-19-2017, 08:06 PM)snippsat Wrote: Pyglet use Python garbage collector to release stuff from memory.I tried that in second method: (Aug-19-2017, 02:54 PM)hbknjr Wrote: Here's an alternate way I tried by deleting the player object, calling gc, and recreating it but no success. But the above code doesn't effect the memory usage at all. I also tried del which obviously doesn't work as song keeps playing in background, assigning self.player=None and calling gc also didn't work. Tell me where I'm wrong.
|