For pyaudio recording on streamlit, how to use session state as a trigger to control the recoding

83 Views Asked by At

How to use streamlit session state as a trigger to control real-time audio recoding? The speaker_array is unable to be accumulated with all the audio data. And the output.wav is 0kb. I think there may be some errors in the while st.session_state['run'] block.

Here is the part of the python code (pyauido setting and intialization has been moved due to too many code):

# Main web UI start here
st.title('️ Mix sound from speaker and microphone App')

st.button('Start', on_click=start_record)
st.button('Stop', on_click=stop_record)

# Define a list to contain multi-stream
streams = [p.open(
    format=FORMAT,
    channels=1,
    rate=RATE,
    input=True,
    frames_per_buffer=FRAMES_PER_BUFFER,
    input_device_index=i)for i in num_sources]

# Open the wave file
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)

# Record the sound from the Speaker and Microphone
try:
    # Initialize lists to hold the audio data
    speaker_array = []
    micro_array = []
    while st.session_state['run']:
        # Read from all streams
        data_array = [np.frombuffer(stream.read(FRAMES_PER_BUFFER), dtype=np.int16) for stream in streams]
        st.write("data", len(data_array[0]))
        speaker_array.append(data_array[0])
        micro_array.append(data_array[1])
        st.write("speaker_array", len(speaker_array[0]))
        speaker_audio = np.concatenate(speaker_array)
        micro_audio = np.concatenate(micro_array)
        # Mix the audio data
        mixed_audio = np.clip((speaker_audio + micro_audio), -32767, 32766).astype(np.int16)
        # Write the mixed audio data to a file
        wf.writeframes(mixed_audio)

except Exception as e:
    st.write(f'An error occurred: {e}')
    st.session_state['run'] = False

# Stop the streams and close PyAudio
for stream in streams:
    stream.stop_stream()
    stream.close()
p.terminate()

# Close the wave file
wf.close()
0

There are 0 best solutions below