Recording System Audio in Windows 10 using PyAudio

Shankhanil Borthakur
3 min readApr 11, 2021

--

If you are trying to record the output from your computer speakers, there is a good chance that you are probably stuck and can’t figure out a way. Don’t worry, I have got it covered up for you in this detailed step-by-step guide. We will use PyAudio and a few other hacks to achieve it.

The official PyAudio build isn’t able to record the system output. But with Windows Vista and above, a new API, WASAPI was introduced, which includes the ability to open a stream to an output device in loopback mode. In this mode, the stream will behave like an input stream, with the ability to record the outgoing audio stream.

To set the mode, one has to set a special flag (AUDCLNT_STREAMFLAGS_LOOPBACK). Since this flag is not supported in the official build one needs to edit PortAudio as well as PyAudio, to add loopback support.

Let's get started…

Step 1 : Install PyAudio

Firstly, you need to install PyAudio properly with all the dependencies in the correct order. You can install it using .whl wheel file. Check out the video below for the complete procedure.

Step 2 : Enable Stereo Mixer

In the Windows control panel open “Sound” settings.

Under “Recording” settings, right-click on “Stereo Mix” and click “Enable” to be able to use it.

Step 3 : Connect PyAudio to your stereo mixer, this way :

p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
input_device_index = dev_index,
frames_per_buffer = CHUNK)

where dev_index is an index of your stereo mixer. In our case dev_index = 2

Step 4 : To get the required index you can list your devices :

for i in range(p.get_device_count()):
print p.get_device_info_by_index(i)

Also, you can add the next code to automatically get index by device name :

for i in range(p.get_device_count()):
dev = p.get_device_info_by_index(i)
if (dev['name'] == 'Stereo Mix (Realtek(R) Audio)' and dev['hostApi'] == 0):
dev_index = dev['index'];
print('dev_index', dev_index)

Step 5 : Continue to work with PyAudio as in the case of recording from a microphone

data = stream.read(CHUNK)

Here is the complete code…

import pyaudio
import wave
sound = True
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 1000
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
input_device_index = 2,
frames_per_buffer=CHUNK)
print(“* recording”)frames = []for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print(“* done recording”)stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, ‘wb’)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b’’.join(frames))
wf.close()

I hope it works out for you. Happy Coding!!

--

--