Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record speakers output with PyAudio

Tags:

python

pyaudio

I'm trying to record the output from my computer speakers with PyAudio.
I tried to modify the code example given in the PyAudio documentation, but it doesn't work.

Technically, there's no error. I obtain the file output.wav and I can open it, but there's no sound. On Audacity, I can only see a straight line.

What's going wrong?

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

SPEAKERS = p.get_default_output_device_info()["hostApi"] #The part I have modified

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK,
                input_host_api_specific_stream_info=SPEAKERS) #The part I have modified

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()
like image 772
Openclosed Avatar asked Oct 26 '14 13:10

Openclosed


People also ask

What can you do with PyAudio?

Introduction. PyAudio provides Python bindings for PortAudio, the cross-platform audio I/O library. With PyAudio, you can easily use Python to play and record audio on a variety of platforms.


2 Answers

In case someone is still stumbling over this like me, I found a PyAudio fork to record the output on windows.

Explanation:

The official PyAudio build isn't able to record the 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.

New option:

"as_loopback":(true|false)

like image 180
mate Avatar answered Sep 30 '22 02:09

mate


I got to record my speaker output with pyaudio with some configuration and code from pyaudio's documentation.

Code

"""PyAudio example: Record a few seconds of audio and save to a WAVE file."""

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                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()

Configuration

First, with pulseaudio running, create a loopback device:

pacmd load-module module-loopback latency_msec=5

Then set the default (fallback) to this loopback device in pavucontrol:

Pavu control example

Then you can start the script, wait 5 seconds, and you should have an output.wav.

like image 23
antoineMoPa Avatar answered Sep 30 '22 00:09

antoineMoPa