Reputation: 547
I'm trying to detect system sounds on windows and I figured I could use the pyaudio module since winrt didn't work for me. I've got this code that lists all the devices, and I know I can open streams with pyaudio
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
dev = p.get_device_info_by_index(i)
print(dev)
but how can I tell whether any of these devices are currently outputting sound? Do I open a stream for each one and take the mean square root of the bytes? If this is an XY problem and I'd be better off using another module, please let me know
Upvotes: 3
Views: 4086
Reputation: 23
There's a simple way to do it.
import time
from pycaw.pycaw import AudioUtilities
def is_audio_playing():
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
if session.State == 1: # State == 1 means the audio session is active
return True
return False
while True:
if is_audio_playing():
print("Audio is currently playing.")
else:
print("No audio is playing.")
time.sleep(1)
Upvotes: 0
Reputation: 395
In python I didn't find any very effective module to retrieve the internal audio of a pc, rather I found a way to simulate the output devices as Input using Stereo Mixer on windows platform.
First enable Stereo Mixer on your windows environment.
After that find the index on which the stereo mixer is located using this code :
import pyaudio
p = pyaudio.PyAudio()
for i in range(p.get_device_count()):
print("\n\n Index " + str(i) + " :\n")
dev = p.get_device_info_by_index(i)
print(dev.get('name'))
print("------------------------------------------------------------")
This code will list all the audio devices along with their indexes. Note the index of Stereo Mixer in your pc.
Here comes the main code to detect sound, replace the device variable's value with the index of Stereo Mixer. For me it was 2.
import pyaudio
import audioop
p = pyaudio.PyAudio()
CHUNK = 1024
FORMAT = pyaudio.paInt16
RATE = 44100
silent_threshold = 1
device = 2
stream = p.open(format=FORMAT, channels = p.get_device_info_by_index(device).get('maxInputChannels') , rate=RATE, input = True , frames_per_buffer=CHUNK , input_device_index = device)
while True:
data=stream.read(CHUNK)
threshold = audioop.max(data , 2)
print(threshold)
if threshold > silent_threshold :
print("Sound found at index " + str(device))
else :
print("Sound not found at index " + str(device))
p.terminate()
Note the use of silent_threshold, the more you increase its value the less reactive it becomes. For example if you want to detect absolute silence use 1 or to detect quietness use 20 , it depends upon your sound playback on your pc.
Upvotes: 1
Reputation: 51
I've done this before with a library called PyCaw (Python Core Audio for Windows)
first pip install pycaw
For some reason this install would only work when running as administrator, but that could be an issue specific to my machine
The following will list the processes currently outputting audio.
from pycaw.pycaw import AudioUtilities
sessions = AudioUtilities.GetAllSessions()
for session in sessions:
print(session.Process)
for some reason it seems to always have a None reference at the end, but you should be able to deal with that pretty easily
Upvotes: 2