Last active
January 6, 2024 05:44
-
-
Save ChronoMonochrome/f56014ad06d107e02c1387ea61a62a7a to your computer and use it in GitHub Desktop.
Python script for recording audio from speakers and streaming over RTSP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A simple example of recording audio from speakers and streaming over RTSP protocol. | |
Requires pyaudiowpatch and RTSP server, e.g. https://github.com/bluenviron/mediamtx | |
""" | |
import pyaudiowpatch as pyaudio | |
import subprocess | |
import time | |
import wave | |
CHUNK_SIZE = 512 | |
def main(): | |
with pyaudio.PyAudio() as p: | |
""" | |
Create PyAudio instance via context manager. | |
""" | |
try: | |
# Get default WASAPI info | |
wasapi_info = p.get_host_api_info_by_type(pyaudio.paWASAPI) | |
except OSError: | |
print("Looks like WASAPI is not available on the system. Exiting...") | |
exit() | |
# Get default WASAPI speakers | |
default_speakers = p.get_device_info_by_index(wasapi_info["defaultOutputDevice"]) | |
if not default_speakers["isLoopbackDevice"]: | |
for loopback in p.get_loopback_device_info_generator(): | |
""" | |
Try to find loopback device with same name(and [Loopback suffix]). | |
Unfortunately, this is the most adequate way at the moment. | |
""" | |
if default_speakers["name"] in loopback["name"]: | |
default_speakers = loopback | |
break | |
else: | |
print("Default loopback output device not found.\n\nRun `python -m pyaudiowpatch` to check available devices.\nExiting...\n") | |
exit() | |
print(f"Recording from: ({default_speakers['index']}){default_speakers['name']}") | |
ffmpeg_command = [ | |
"ffmpeg", | |
"-re", | |
"-f", "s16le", | |
"-ar", str(int(default_speakers["defaultSampleRate"])), | |
"-ac", str(default_speakers["maxInputChannels"]), | |
"-i", "-", | |
"-c:a", "libvorbis", | |
"-f", "rtsp", | |
"-rtsp_transport", "tcp", | |
"rtsp://localhost:8554/mystream" | |
] | |
ffmpeg_process = subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE) | |
def callback(in_data, frame_count, time_info, status): | |
ffmpeg_process.stdin.write(in_data) | |
return (in_data, pyaudio.paContinue) | |
with p.open(format=pyaudio.paInt16, | |
channels=default_speakers["maxInputChannels"], | |
rate=int(default_speakers["defaultSampleRate"]), | |
frames_per_buffer=CHUNK_SIZE, | |
input=True, | |
input_device_index=default_speakers["index"], | |
stream_callback=callback | |
) as stream: | |
print(f"Recording audio and streaming at rtsp://localhost:8554/mystream") | |
while True: | |
try: | |
time.sleep(1) | |
except KeyboardInterrupt: | |
break | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment