whitphx/streamlit-webrtc

multi users audio process

Esdsnqxz opened this issue · 0 comments

I am trying deploy a streaming kws app using streamlit and stream-webrtc , it seems like can't handdle simultaneous access from multi users .

Streamlit's document says when a user connects to streamlit, it spin up a thread just for them and run the app for that user. Does it mean i don't need do other process ensure multiple access?

During the testing phase after deploying the app, i use 2 pc visit the app web simultaneously, but when one working ,the other is unresponsive.
heres my code:


def normal_kwsinput(kws_txt):
    ...
    return kws, len(kws), kws_dict, kws_length


def main():     
    kws_txt = st.text_input("Type KeyWords:")
    app_stk(kws_txt)
    

def app_stk(kws_txt):
    kws,kws_num,kws_dict,kws_length = normal_kwsinput(kws_txt)
    webrtc_ctx = webrtc_streamer(
        key="KeywordSpotting",
        mode=WebRtcMode.SENDONLY,
        audio_receiver_size=1024,
        rtc_configuration={"iceServers": get_ice_servers()},
        media_stream_constraints={"video": False, "audio": True},
    )
    
    status_indicator = st.empty()
    
    if not webrtc_ctx.state.playing:
        return

    status_indicator.write("Loading...")
    text_output = st.empty()

    lib = CDLL("./libovkws.so.2")
    Init = lib.ovkws_main_init
    Init.argtypes= [POINTER(c_char_p),POINTER(c_int),c_int]
    Init.restype= c_void_p
    
    Process = lib.ovkws_main_process
    Process.argtypes = [POINTER(c_int16),c_void_p]
    Process.restype = c_int
    
    CleanUp = lib.ovkws_main_cleanup
    CleanUp.argtypes = [c_void_p]
    CleanUp.restype = None
    
    process_ptr = c_int16 * 160
    mic_input = process_ptr()
    
    init_len_ptr = c_int * kws_num
    init_input_len = init_len_ptr()
    for i in range(kws_num):
        init_input_len[i] = kws_length[i]
    kws_string = [s.encode() for s in kws]
    kws_string_array = (c_char_p* len(kws_string))(*kws_string)
    instance = Init(kws_string_array,init_input_len,kws_num)
    
    while True:
        if webrtc_ctx.audio_receiver:
            
            sound_chunk = pydub.AudioSegment.empty()
            try:
                audio_frames = webrtc_ctx.audio_receiver.get_frames(timeout=1)  
            except queue.Empty:
                status_indicator.write("No frame arrived.")
                continue

            status_indicator.write("Running. Say something....")

            for audio_frame in audio_frames:
                sound = pydub.AudioSegment(
                    data=audio_frame.to_ndarray().tobytes(),  
                    sample_width=audio_frame.format.bytes,   
                    frame_rate=audio_frame.sample_rate,        
                    channels=len(audio_frame.layout.channels),  
                )
                sound_chunk += sound
                
            if len(sound_chunk) > 0:
                sound_chunk = sound_chunk.set_channels(1).set_frame_rate(16000)
                buffer = sound_chunk.get_array_of_samples()
                for i in range(2):
                    for j in range(160): 
                        mic_input[j] = buffer[i*160 + j] 
                    result = Process(mic_input,instance)                    
                    if (result != -1):
                        text_output.markdown(f"**COMMAND:** {kws_dict[result]}")
        else:
            status_indicator.write("AudioReciver is not set. Abort.")
            break