I'm building a live audio streaming feature with Flask-SocketIO and sounddevice
. Audio is captured from a microphone and emitted in chunks to clients via Socket.IO rooms.
Problem: When I listen to the streamed audio on the client, I hear a periodic beeping noise roughly twice per second, which interrupts the audio stream. It sounds like a timing or threading issue.
import eventlet
eventlet.monkey_patch()
I use sounddevice to capture audio.
gunicorn -k eventlet -w 1 -t 4 -b 0.0.0.0:5001 app:app
Deployment command.
import sounddevice as sd
import threading
from extensions import sio
from flask_socketio import join_room, leave_room
class AudioStreamer:
def __init__(self, sample_rate=44100, channels=2, chunk_size=1024):
self.sample_rate = sample_rate
self.channels = channels
self.chunk_size = chunk_size
self.thread = None
self.room = 'audio_listeners'
self.is_running = False
def start(self):
if self.is_running:
return
self.is_running = True
self.thread = threading.Thread(target=self._stream_audio, daemon=True).start()
print('[AudioStreamer] Audio thread started.')
def stop(self):
if not self.is_running:
return
self.is_running = False
self.thread.join(timeout=1)
print('[AudioStreamer] Audio thread stopped.')
def add_client(self, sid):
join_room(self.room, sid=sid)
if not self.is_running:
self.start()
def remove_client(self, sid):
leave_room(self.room, sid=sid)
# TODO: stop streaming if no clients remain
def _stream_audio(self):
try:
with sd.InputStream(samplerate=self.sample_rate, channels=self.channels, dtype='int16') as stream:
while self.is_running:
data, _ = stream.read(self.chunk_size)
sio.emit('audio_chunk', data.tobytes(), room=self.room)
sio.sleep(0)
except Exception as e:
print(f'[AudioStreamer] Error: {e}')
Here is an example that works that I've tried:
import eventlet
eventlet.monkey_patch()
from flask import Flask, render_template
from flask_socketio import SocketIO
import sounddevice as sd
import threading
app = Flask(__name__)
socketio = SocketIO(app)
sample_rate = 44100
channels = 2
chunk_size = 1024
def audio_stream_thread():
with sd.InputStream(samplerate=sample_rate, channels=channels, dtype='int16') as stream:
while True:
data, _ = stream.read(chunk_size)
# send raw PCM bytes to all connected clients
socketio.emit('audio_chunk', data.tobytes())
socketio.sleep(0)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
threading.Thread(target=audio_stream_thread, daemon=True).start()
socketio.run(app, host='0.0.0.0', port=5001, allow_unsafe_werkzeug=True)
I found the problem. It is a hardware or a driver level issue. Because even in an ffmpeg recorded video I can hear the beeping. (My mic is also a webcam.) But if the camera is off the mic works fine. So yeah.