Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Ashesh3/cf9a54297ca3644e7fc006c404d3403b to your computer and use it in GitHub Desktop.
Save Ashesh3/cf9a54297ca3644e7fc006c404d3403b to your computer and use it in GitHub Desktop.
Remote Microphone Stream: A Python-based system for real-time audio streaming from a microphone on one machine to another over WebSockets, enabling applications like remote monitoring and broadcasting.
Remote Microphone Stream: A Python-based system for real-time audio streaming from a microphone on one machine to another over WebSockets, enabling applications like remote monitoring and broadcasting.

Remote Microphone Stream

This project enables real-time audio streaming from a microphone on one machine (the sender) to another machine (the receiver) over the internet using WebSockets. It's useful for remote monitoring or broadcasting audio from a microphone source.

Components

The project consists of three main components:

  • sender.py: Captures audio from the microphone and sends it to the server using WebSockets.
  • server.py: A WebSocket server that relays audio data from the sender to the receiver.
  • receiver.py: Connects to the server via WebSocket and plays the received audio stream.

Requirements

  • Python 3.x
  • pyaudio for audio capture and playback.
  • websocket-client for WebSocket communication in sender and receiver.
  • aiohttp for the WebSocket server.
  • numpy for audio data manipulation in the receiver.

Installation

Ensure you have Python 3.x installed. Then, install the required Python packages:

pip install pyaudio websocket-client aiohttp numpy

Running the Components

  1. Server: Start the server component first by running python server.py.
  2. Sender: Run the sender component on the machine with the microphone you wish to stream from with python sender.py.
  3. Receiver: Finally, run the receiver component on the machine where you want to listen to the audio stream with python receiver.py.

Additional Notes

  • The system is designed to work over networks, but ensure your firewall and network settings allow for the required WebSocket connections.
  • The WS_URL in both sender and receiver scripts should be updated to match your server's address and port.
  • This is a basic implementation intended for educational purposes or as a foundation for more complex streaming solutions.

Tags

remote-audio-streaming, live-audio-streaming, python-websockets, audio-over-websocket, real-time-microphone-streaming, microphone-to-pc-streaming, web-audio-api, audio-capture, streaming-audio-data, audio-broadcasting, websockets-audio-transport, remote-sound-monitoring, sound-streaming, python-audio-processing, network-audio-stream, microphone-audio-transmission, audio-streaming-application, voice-streaming, remote-listening, audio-data-transfer

"""
This script is the receiver component of a remote microphone streaming system.
It connects to a specified WebSocket server, receives audio data streamed from a sender,
and plays it back in real-time. It uses pyaudio for audio playback and numpy for
manipulation of the audio data.
Usage:
Run the script with Python 3.x. It will automatically connect to the WebSocket server
specified in the WS_URL variable and start playing received audio data.
To stop the script, focus on the terminal and press Ctrl+C.
"""
import pyaudio
import websocket
import threading
import numpy as np
# Audio configuration
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024 * 10
# WebSocket
WS_URL = (
"ws://audioendpoint.yourserver.com/ws?password=demopassword"
)
def on_message(ws, message):
# Convert the message data to a numpy array of the correct type
data = np.frombuffer(message, dtype=np.int16)
stream.write(data.tobytes())
def on_error(ws, error):
print(error)
def on_open(ws):
print("Opened connection")
def send_panic_and_exit():
print("Panic! Sending 'panic' message...")
ws.send("panic")
ws.close()
stream.stop_stream()
stream.close()
p.terminate()
print("Terminated. Exiting.")
exit()
if __name__ == "__main__":
ws = websocket.WebSocketApp(
WS_URL, on_message=on_message, on_error=on_error
)
p = pyaudio.PyAudio()
stream = p.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
output=True,
frames_per_buffer=CHUNK,
)
wst = threading.Thread(target=lambda: ws.run_forever())
wst.daemon = True
wst.start()
print("Receiving... Press Ctrl+C to stop")
try:
while True:
pass # Keep the main thread alive
except KeyboardInterrupt:
send_panic_and_exit()
"""
This script functions as the sender in a remote microphone streaming setup.
It captures audio from the system's default microphone using pyaudio, encodes this
audio data, and sends it over a WebSocket connection to a server. The server
then relays this data to one or more receivers.
Usage:
Execute the script with Python 3.x to begin capturing and streaming audio.
The script sends audio data to the WebSocket server specified in WS_URL.
If a "panic" message is received from the server, the script stops streaming,
closes the audio stream, and exits.
"""
import pyaudio
import websocket
import threading
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024 * 10
stream = None
p = pyaudio.PyAudio()
WS_URL = (
"ws://audioendpoint.yourserver.com/ws?password=demopassword"
)
def on_message(ws, message):
print("Received message from server", message)
if message == "panic":
stream.stop_stream()
stream.close()
p.terminate()
print("Terminated")
ws.close()
def on_error(ws, error):
print(error)
def on_open(ws):
def run(*args):
global stream
stream = p.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
)
print("Recording...")
while True:
data = stream.read(CHUNK)
ws.send(data, opcode=websocket.ABNF.OPCODE_BINARY)
stream.stop_stream()
stream.close()
p.terminate()
print("Terminated")
ws.close()
thread = threading.Thread(target=run)
thread.start()
if __name__ == "__main__":
ws = websocket.WebSocketApp(WS_URL, on_message=on_message, on_error=on_error)
ws.on_open = on_open
ws.run_forever()
"""
A WebSocket server designed to relay audio data from a sender to a receiver
in a remote microphone streaming system. It uses aiohttp to handle WebSocket
connections. The server listens for incoming audio data on a specified port,
authenticates clients based on a query parameter (password), and forwards audio
data to all connected and authenticated receiver clients.
Usage:
Start the server by running this script with Python 3.x. It will listen for
connections on 0.0.0.0 at the port defined at the bottom of the script.
Senders and receivers connect to this server using the WebSocket protocol,
allowing for real-time audio streaming from the sender to the receiver.
"""
import asyncio
from aiohttp import web
# Set of connected WebSocket clients
connected = set()
# Your predefined password
PASSWORD = "demopassword"
async def websocket_handler(request):
# Check password from query parameters
if request.query.get("password") != PASSWORD:
return web.Response(text="Unauthorized", status=401)
ws = web.WebSocketResponse()
await ws.prepare(request)
print("A new client connected.")
connected.add(ws)
async for msg in ws:
if msg.type == web.WSMsgType.TEXT:
# Broadcast incoming text message to all connected websockets
for socket in connected:
if socket != ws:
await socket.send_str(msg.data)
elif msg.type == web.WSMsgType.BINARY:
# Broadcast incoming binary message to all connected websockets
for socket in connected:
if socket != ws:
try:
await socket.send_bytes(msg.data)
except Exception as e:
pass
elif msg.type == web.WSMsgType.ERROR:
print("ws connection closed with exception %s" % ws.exception())
print("Client disconnected.")
connected.remove(ws)
return ws
async def init_app():
app = web.Application()
app.add_routes([web.get("/ws", websocket_handler)])
return app
loop = asyncio.get_event_loop()
app = loop.run_until_complete(init_app())
web.run_app(app, host="0.0.0.0", port=80) # Your host and port settings here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment