问题
This is my current code:
import winsound as wav
wav.PlaySound("music.wav", wav.SND_LOOP | wav.SND_ASYNC)
input()
wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)
From the python winsound documentation: "[Winsound's] interpretation [of the file] depends on the value of flags, which can be a bitwise ORed combination of the constants described below"
The music itself plays asynchronously, and loops. However, when the above code plays the beep, it throws an error (sprites.py is the code's file):
Traceback (most recent call last):
File ".../sprites.py", line 5, in <module>
wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)
RuntimeError: Failed to play sound
Swapping SND_ASYNC
and SND_NOSTOP
produces an identical error, and removing the SND_NOSTOP
results in the beep playing, but the music cuts out.
Why is this happening, and if it's unfixable, is there another way I can cause the beep to play without cutting off the music?
The Sound files are here, if that's important.
This question exists, however it does not appear to have an answer.
回答1:
You are combing flags just fine; that's not the issue. The problem is that the API you are using doesn't support playing more than one sound at a time.
In other words, the exception is thrown because there is already a sound being played, in a loop. The SND_NOSTOP
flag is only of use when you want to prevent a currently playing sound from being interrupted; the exception is raised to indicate that sound is playing right now. Without the flag the old sound is stopped and the new sound is played.
The winsound
Python module is little more than a thin wrapper around the Windows API PlaySound function, which states:
SND_NOSTOP
The specified sound event will yield to another sound event that is already playing in the same process. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound.If this flag is not specified, PlaySound attempts to stop any sound that is currently playing in the same process. Sounds played in other processes are not affected.
Use the flag to optimistically play sounds only if nothing else is currently playing:
try:
wav.PlaySound("beep.wav", wav.SND_ASYNC | wav.SND_NOSTOP)
except RuntimeError:
# sound api busy with another sound, tough luck
pass
In order to play sounds simultaneously you need an API that can mix sounds; PlaySound
can't do this, and there is nothing else in the standard library that can.
You need something than lets you use the DirectSound API instead. Like the pyglet library. This library includes an excellent audio API that should make it trivial to combine looped music with occasional other sound effects playing in parallel.
来源:https://stackoverflow.com/questions/44492900/python-using-multiple-flags-for-winsound