on_player_eos event not working when trying to play through a list of mp3 files with Pyglet

98 views
Skip to first unread message

Mitchell Barton

unread,
Jun 16, 2016, 5:45:15 PM6/16/16
to pyglet-users

I'm trying to shuffle a list of mp3 files and then play through them with pyglet. Once the player runs out of sources I want to re-shuffle the list, and then play through them again. This process would happen infinitely. I have been able to get pyglet to play through the sources once, but the on_player_eos event is never fired when I run out of sources. I'm not sure exactly what I am doing wrong, or if I am approaching it in the wrong way. I've tried a couple ways of doing it, but have had no luck getting it to work. Here is the code

import os, sys, random, pyglet
from random import shuffle

song1 = pyglet.media.load('beats/breathe.mp3')
song2 = pyglet.media.load('beats/everything.mp3')
song3 = pyglet.media.load('beats/jazz.mp3')
player = pyglet.media.Player()

# Play beatz

def beatz():
    playlist = [song1, song2, song3]
    shuffle(playlist)
    player.queue(playlist[0])
    player.queue(playlist[1])
    player.queue(playlist[2])
    player.play()

def on_player_eos():
    print('repeating')
    beatz()

player.on_player_eos = on_player_eos

I have also tried replacing the 'player.on_player_eos = on_player_eos' with

player.push_handlers(on_player_eos)

But it doesnt seem to do anything either. Any help appreciated.

Benjamin Moran

unread,
Jun 17, 2016, 10:17:58 AM6/17/16
to pyglet-users
Hi Mitchell,

I was curious about this, because I'm not very faimilar with the pyglet.media module myself either. I gave it a try with some tiny *.wav files (since I don't have avbin), and it errored out due to the sources already being queued to the player on the second loop. This might only be because my wav files were so small, so using static sources (streaming=False) may not be necessary for you.


import os, sys, random, pyglet
from random import
shuffle

song1
= pyglet.media.load('jump.wav', streaming=False)
song2
= pyglet.media.load('pickup.wav', streaming=False)
song3
= pyglet.media.load('laser.wav', streaming=False)

player
= pyglet.media.Player()

# Play beatz

def beatz():
    playlist
= [song1, song2, song3]
    shuffle
(playlist)
    player
.queue(playlist[0])
    player
.queue(playlist[1])
    player
.queue(playlist[2])
    player
.play()

def on_player_eos():
   
print('repeating')
    beatz
()

player
.on_player_eos = on_player_eos

if __name__ == "__main__":
    beatz
()
    pyglet
.app.run()

Benjamin Moran

unread,
Jun 17, 2016, 9:17:44 PM6/17/16
to pyglet-users
Ah, I realize that my reply wasn't clear. The code I posted works fine. If it doesn't work for you, please share your error message.

Mitchell Barton

unread,
Jun 24, 2016, 6:17:38 PM6/24/16
to pyglet-users
Thanks Benjamin, 

Ive been trying your code, and a few other things, at first I wasn't able to get it to work, but I was able to fix it just today and your code worked great! Thank you so much!

Mitchell Barton



On Fri, Jun 17, 2016 at 7:17 PM Benjamin Moran <benmo...@gmail.com> wrote:
Ah, I realize that my reply wasn't clear. The code I posted works fine. If it doesn't work for you, please share your error message.

--
You received this message because you are subscribed to a topic in the Google Groups "pyglet-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyglet-users/uxgMsN-i6Ro/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pyglet-users...@googlegroups.com.
To post to this group, send email to pyglet...@googlegroups.com.
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.

Benjamin Moran

unread,
Jun 25, 2016, 8:16:45 AM6/25/16
to pyglet-users
That's great. I'm glad that helped.
Just curious though, was it necessary for you to use static sources as well? (The streaming=False parameter).

Mitchell Barton

unread,
Jun 25, 2016, 11:59:31 AM6/25/16
to pyglet-users
Yeah, I kept on getting the same error you mentioned of the source being queued already if they weren't static. So setting them as static resources was vital. I did have some problems with certain sounds, for some reason one mp3 files on_player_eos event wasnt firing, but all the other sources I had worked fine. 

I'm now trying to add a few other things to my code, running Terminal's 'say' command on top of the music being played with pyglet. I play the songs I have, and then have terminal pick random words out of a list that then 'says' them repeatedly. It seems to work at first, but then freezes, running the code forever and not responding to any window events until I force quit the Python interpreter. 

So my question is, is it possible to run commands in the command line while a pyglet application is running without the application freezing?

Here is my code

Screen Shot 2016-06-25 at 9.40.23 AM.pngScreen Shot 2016-06-25 at 9.43.08 AM.png

On Sat, Jun 25, 2016 at 9:57 AM Mitchell Barton <mitchellcl...@gmail.com> wrote:
Yeah, I kept on getting the same error you mentioned of the source being queued already if they weren't static. So setting them as static resources was vital. I did have some problems with certain sounds, for some reason one mp3 files on_player_eos event wasnt firing, but all the other sources I had worked fine. 

I'm now trying to add a few other things to my code, running Terminal's 'say' command on top of the music being played with pyglet. I play the songs I have, and then have terminal pick random words out of a list that then 'says' them repeatedly. It seems to work at first, but then freezes, running the code forever and not responding to any window events until I force quit the Python interpreter. 

So my question is, is it possible to run commands in the command line while a pyglet application is running without the application freezing?

Here is my code

Screen Shot 2016-06-25 at 9.40.23 AM.pngScreen Shot 2016-06-25 at 9.43.08 AM.png

Benjamin Moran

unread,
Jun 25, 2016, 10:16:09 PM6/25/16
to pyglet-users
OK, so in the documentation I can see the official description of StreamingSources is:  "StreamingSource A source that is decoded as it is being played, and can only be queued once."
So I guess that answers the question about why your original code didn't work!  I thin maybe the error message could be better. Right now it just says "already queued", but It might be better to say something like "Cannot queue StreamingSources more than once". That would immediately give users some idea that maybe that should at least find out what a StreamingSource is anyway, and why it's not going to work.

About your speech code, I haven't had a chance to test it here, but I there shouldn't be anything specific to pyglet that would prevent running subprocesses. I would guess that the hang is caused by waiting for return codes or something.

I've not used os.system in a long time, but it might be a good idea to use the subprocess module instead. The subprocess.run(["say", random.choice(hype)]) should work as you expect.

Mitchell Barton

unread,
Jun 25, 2016, 11:17:28 PM6/25/16
to pyglet-users
Awesome, I will try that out and see if I can find a solution.

In regards to the error message, I agree, something a bit more descriptive probably could have pointed me in the right direction quicker. The documentation says it pretty clearly, but I must have just missed it. Thank you for your help!

--

Elliot Hallmark

unread,
Jun 25, 2016, 11:18:14 PM6/25/16
to pyglet...@googlegroups.com

Subprocess.popen is non blocking, fyi.

Mitchell Barton

unread,
Jun 26, 2016, 12:19:04 AM6/26/16
to pyglet...@googlegroups.com
So I just tried using subprocess.run, and subprocess.popen to run the commands, but they still werent working. Maybe I'm missing something else that is causing me trouble. I will keep trying though

On Sat, Jun 25, 2016 at 9:18 PM Elliot Hallmark <Permaf...@gmail.com> wrote:

Subprocess.popen is non blocking, fyi.

Mitchell Barton

unread,
Jun 28, 2016, 5:50:25 PM6/28/16
to pyglet...@googlegroups.com

An update - I was able to find a solution to the hang that was happening when I would try closing my pyglet application. I replaced subprocess.call with subprocess.popen, which seems better, but this wasn't what was actually causing the problem. It was the timer I was using from the threading module. It looks like the timer was never being stopped on close, and that was affecting how pyglet was closing. So i added 't.cancel' on closing events to fix it. Here is the updated code:

pyglet.options['audio'] = ('openal', 'silent')
window = pyglet.window.Window()

be = ['is', 'was', 'will be', 'is not']

song2 = pyglet.media.load('beats/knock.mp3', streaming=False)
song12 = pyglet.media.load('beats/drop-2.mp3', streaming=False)
player = pyglet.media.Player()

def beatz():
    playlist = [song2, song12]
    shuffle(playlist)
    player.queue(playlist[0])
    player.queue(playlist[1])
    player.play()

def on_player_eos():
    print('repeating')
    beatz()

player.push_handlers(on_player_eos)

#### WORDS STUFF #####

barLen = list(range(1,10))

timez = [.5, .75, 1.0, 1.5, 2.0]

def rap():
    t = Timer(random.choice(timez), rap)
    @window.event
    def on_key_press(symbol, modifiers):
        if symbol == key.A:
            r.terminate()
            t.cancel()
            print('exiting')
            pyglet.app.exit()

    @window.event
    def on_close():
        r.terminate()
        t.cancel()
        print('exiting')
        pyglet.app.exit()

    bar = ' '.join(random.choice(be) for _ in range(random.choice(barLen)))
    r = subprocess.Popen('say ' + bar, shell=True)
    r.wait()
    sys.stdout.flush()
    t.start()

def freestyle():
    beatz()
    t = Timer(1.5, rap)
    t.start()

if __name__ == "__main__":
    freestyle()
    pyglet.app.run()

This works great. Thanks so much for all your help!

Reply all
Reply to author
Forward
0 new messages