1

I'm using StringIO to stream music data, but it appears that when I run with pygame.mixer.music.load(), my application won't exit. Even if I use close():

def PlaySong(self, song_id):
    song = StringIO.StringIO(resp.read())
    self.pygame.mixer.music.load(song)
    ....

The function will return, but the application has to be killed. If I save the response to a file, then load the filename, it will close. Can anybody help? I don't want to use local storage.

More info. I did a strace on both opening from a file, and using stringio, strace will exit properly for both instances. The straces look clean.

Working code:

def playsong():
    mp3 = "/home/adam/Documents/pinyin/pinyinchart_win/pinyin/zuo2.mp3"
    #with open(mp3, "rb") as outfile:
    #    song = outfile.read()

    #io = StringIO.StringIO(song)
    pygame.init()
    pygame.mixer.music.load(mp3)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(50)

    #io.close()
    #outfile.close()

Not working code:

def playsong():
    mp3 = "/home/adam/Documents/pinyin/pinyinchart_win/pinyin/zuo2.mp3"
    with open(mp3, "rb") as outfile:
        song = outfile.read()

    io = StringIO.StringIO(song)
    pygame.init()
    #pygame.mixer.music.load(io)
    pygame.mixer.music.load(mp3)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(50)

    io.close()
    outfile.close()
ptomato
  • 56,175
  • 13
  • 112
  • 165
AdamL
  • 41
  • 4

4 Answers4

0

Try sys.exit() and the built-in function exit().

alexpinho98
  • 909
  • 8
  • 14
0

I've encountered this problem frequently while trying to run pykaraoke; only tonight did I trace it to pygame.mixer.music.play(). The strange thing is, it only happens on multiprocessor systems; if I do the test on a single-processor system, or boot Linux with "maxcpus=1", it doesn't happen. Otherwise, the hard hang happens regularly, and I have to use SIGKILL, because SIGTERM doesn't work.

So I think it's a bug in pygame, or something it depends on. I just sent a Python script and very short (50k) MP3 file to the pygame-users mailing list; if anything happens, I'll report back.

UPDATE: I was able to reproduce the bug with a program that interacted directly with SDL_mixer. The answer is, it's a bug in smpeg. Rebuild SDL_mixer with support for libmad turned on. You also have to de-install smpeg completely, because SDL_mixer will try to use it in favor of libmad.

ulatekh
  • 1,311
  • 1
  • 14
  • 19
0

I have the same problem - apparently pygame is pretty bad at cleaning up after itself, and calling pygame.quit() sometimes just hangs. Even sys.exit() doesn't actually exit, maybe because of some error handlers installed by pygame.init(). According to people on the #pygame IRC channel, this problem will never be fixed and pygame is a dead project (!?), even though there still seems to be some activity in the mailing list and on the project website. Maybe this will be fixed in pygame2...

anarcat
  • 5,605
  • 4
  • 32
  • 38
0

I've seen this behavior when Python's threading support is used. It's possible that pygame is using threads and that some of them are being implicitly spawned, not marked as "daemon" threads and not joined at the time that you're trying to .quit().

Note that sys.exit() is NOT likely to work because that throws the SystemExit exception (which may be caught, particularly by atexit handlers among possibilities). Also sys.exit() will only exit the thread in which it was processed, other threads will still be running. (StackOverflow: Issue with sys.exit() in pygame for more details on that).

Here's another: StackOverflow: pygame screen freezes when I close it.

I tried a number of Google searches on the phrases: pygame quit {fails, hangs, stalls} ... and most of them led to discussions similar to these that I've provided here.

The consensus seems to be that you want to structure your threads to handle a "quit" event, such that all of them call pygame.quit() before your main (parent) process attempts to use sys.exit() or simply drops out of the __main__ suite.

Beyond that I would also check to see if some process, thread, or driver is getting stalled on your music device. In Unix-like systems that would show up in the process listing (ps command output) as being in the "D" state. (I'm assuming, by your mention of strace that you're running on Linux).

Community
  • 1
  • 1
Jim Dennis
  • 17,054
  • 13
  • 68
  • 116