Why does pygame.mixer.Sound().play() return None?

Question:

According to the pygame documentation, pygame.mixer.Sound().play() should return a Channel object. It actually does.

But sometimes, it seems to return None because the very next line, I get this error:

NoneType has no attribute set_volume

when I try to type

channel = music.play(-1)
channel.set_volume(0.5)

Of course the error can happen because the sound is very short, but the error can’t come from there (Is 5’38" shorter than the time python needs to shift from one line to the next?)

I also Ctrl+H all the code to see if I typed somewhere channel = None (because I use multiple threads) – Nothing.

Does anybody had the same problem? Is that a pygame bug?

I use python 3.8.2, pygame 2.0.1 and Windows.


Currently I bypass the error rather than fix it like that:

channel = None
while channel is None:
    channel = music.play()
channel.set_volume(0.5)

But… it doesn’t seem to help very much: the game freezes, because pygame constantly returns None.

Asked By: D_00

||

Answers:

Sound.play() returns None if it can’t find a channel to play the sound on, so you have to check the return value. Using the while loop is obviously a bad idea.

Note that you can either set the volumne of not only an entire Channel, but also on a Sound object, too. So you could set the volume of your music sound before trying to play it:

music.set_volume(0.5)
music.play()

If you want to make sure that Sound is played, you should get a Channel before and use that Channel to play that Sound, something like this:

# at the start of your game
# ensure there's always one channel that is never picked automatically
pygame.mixer.set_reserved(1)

...

# create your Sound and set the volume
music = pygame.mixer.Sound(...)
music.set_volume(0.5)
music.play()

# get a channel to play the sound
channel = pygame.mixer.find_channel(True) # should always find a channel
channel.play(music)
Answered By: sloth
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.