whitphx / streamlit-webrtc

Real-time video and audio processing on Streamlit
https://discuss.streamlit.io/t/new-component-streamlit-webrtc-a-new-way-to-deal-with-real-time-media-streams/8669
MIT License
1.38k stars 184 forks source link

CPU-heavy task causes frame delay #1494

Open Kogia-sima opened 7 months ago

Kogia-sima commented 7 months ago

Summary

CPU-heavy task inside the while-loop causes video frame delay within the streamlit-webrtc container.

minimal reproduction:

import time
from streamlit_webrtc import webrtc_streamer

ctx = webrtc_streamer(key="example")

while ctx.state.playing:
    # busy loop
    start = time.time()
    while time.time() - start < 0.1:
        pass

Details

I'm building a real-time image recognition application using streamlit-webrtc. However, the video in the application is extremely laggy and delayed. I examined this and found that the above minimal code causes same behavior. I also found that this issue has gone after I inserted manual sleep inside the loop. However, I can't figure out how long sleep is enough to avoid frame delay issue.

ctx = webrtc_streamer(key="example")

while ctx.state.playing:
    # busy loop
    start = time.time()
    while time.time() - start < 0.1:
        pass

    # manual sleep
    time.sleep(0.05)

Question

Environment

Context Version
OS Windows 10 Pro 21H2 (19044.3930)
Shell PowerShell 5.1.19041.3930
Browser Google Chrome 121.0.6167.140 (stable)
Python 3.11.5
streamlit 1.30.0
streamlit-webrtc 0.47.1
thegenerativegeneration commented 7 months ago

I have the same problem, although I'm not even doing anything particularly heavy in my loop.

while ctx.state.playing:
    with lock:
        is_speaking = info["is_speaking"]
        audio_frame_id = info["audio_frame_id"]

I even get delay if the only thing in the while loop is:

while ctx.state.playing:
    pass

The lines above cause a delay of multiple seconds in the video delivered via webrtc:

def video_frame_callback(frame): return frame

My environment is:

OS: macOS Ventura 13.4.1 (arm) Shell: zsh Browser: Firefox 122 Python: 3.10.13 streamlit: 1.31.1 streamlit-webrtc: 0.47.1

whitphx commented 4 months ago

I think it's because Python doesn't execute CPU-bound tasks in parallel even in multiple threads due to the GIL. Off-loading the cpu-heavy tasks to another "process" by using multiprocessing might be a solution.