Dec-24-2024, 04:34 AM
(This post was last modified: Dec-24-2024, 04:37 AM by ultimatecodewarrior.)
Hi All, trying to stream from the Microphone on the Raspberry PI. This chunk of code almost works on the PI to a browser window. I just don't hear any audio. If I clap my hands I can see the audio monitor running on the PI with the number feed spike, so I know it's detecting audio. I think there is something fundamentally wrong how I am sending the sample data to the browser so that the audio control doesn't quite work. Anyone have any suggestions or know of the fix?
from flask import Flask, Response
import pyaudio
import wave
import threading
import time
import numpy as np
app = Flask(__name__)
CHUNK = 1024 # Samples: 1024, 512, 256, 128 frames per buffer
RATE = 44100 # Equivalent to Human Hearing at 40 kHz
CHANNELS =1
BITS_PER_SAMPLE = 16
mic_data=None
str_data=None
#print(mic_data)
#status = 0 frame_count = 1024 #time_info is like a timestamp json
def callback(in_data, frame_count, time_info, status):
global mic_data
global str_data
mic_data = np.fromstring(in_data, dtype=np.int16)
str_data = in_data
print(np.amax(mic_data))
return (in_data, pyaudio.paContinue)
def mic_stream():
global CHUNK
global RATE
global CHANNELS
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback=callback)
stream.start_stream()
while stream.is_active():
time.sleep(0.1)
stream.stop_stream()
stream.close()
p.terminate()
def generate_wav_header():
global RATE
global CHANNELS
global BITS_PER_SAMPLE
datasize = 2000*10**6
o = bytes("RIFF",'ascii') # (4byte) Marks file as RIFF
o += (datasize + 36).to_bytes(4, 'little') # (4byte) File size in bytes excluding this and RIFF marker
o += bytes("WAVE",'ascii') # (4byte) File type
o += bytes("fmt ",'ascii') # (4byte) Format Chunk Marker
o += (16).to_bytes(4, 'little') # (4byte) Length of above format data
o += (1).to_bytes(2, 'little') # (2byte) Format type (1 - PCM)
o += (CHANNELS).to_bytes(2, 'little') # (2byte)
o += (RATE).to_bytes(4, 'little') # (4byte)
o += (RATE * CHANNELS * BITS_PER_SAMPLE // 8).to_bytes(4, 'little') # (4byte)
o += (CHANNELS * BITS_PER_SAMPLE // 8).to_bytes(2, 'little') # (2byte)
o += (BITS_PER_SAMPLE).to_bytes(2, 'little') # (2byte)
o += bytes("data",'ascii') # (4byte) Data Chunk Marker
o += (datasize).to_bytes(4, 'little') # (4byte) Data size in bytes
return o
def generate_audio_stream():
global str_data
wav_header = generate_wav_header()
yield wav_header
while True:
if str_data:
yield str_data
@app.route('/audio_feed')
def audio_feed():
return Response(generate_audio_stream(),
mimetype='audio/wav')
@app.route('/')
def index():
return '''
<html>
<head>
<title>Audio Streaming</title>
</head>
<body>
<button>Record</button>
<h1>Audio Streaming</h1>
<audio controls autoplay>
<source src="/audio_feed" type="audio/wav">
</audio>
</body>
</html>
'''
if __name__ == '__main__':
mic_thread = threading.Thread(target=mic_stream)
mic_thread.start()
app.run(host='0.0.0.0', port=9000, debug=True)
