user3150635
user3150635

Reputation: 547

check if any devices on windows are playing sound python

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

Answers (3)

David Hite
David Hite

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

AI - 2821
AI - 2821

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

Eric Skelton
Eric Skelton

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

Related Questions