Live video in subpage

Hey there,

I’m writing a motion detection / object recognition demo on top of Streamlit and OpenCV. The demo is completely local, so I might as well use a widget toolkit like Tkinter or PyQt, but using Streamlit seems simpler. I can emulate streaming video on the main page of the app with something like this:

# main.py
with st.empty():
    while True:
        grabbed, frame = stream.read()
        if grabbed:
            st.image(frame, channels="BGR") 

But what I actually want to do is to have the main page fetch and process the frames, then have them render on a subpage, like this:

# main.py
view = st.Page("view.py")
app = st.navigation([view])
app.run()

while True:
    grabbed, frame = stream.read()
    if grabbed:
        process(frame)
# view.py
with st.empty():
    st.image(frame, channels="BGR")

I can pass the frame between the pages using a session variable, but the second page doesn’t update while the loop in the first page is running, even if enclose the code in a function decorated with @st.fragment. Any ideas on how to do this, other than to move the rendering code back into the loop?

Edit: added st.navigation to show relation between pages.

Two page scripts will not run concurrently for a single user. For each user viewing your app, only the page they are on is running (or finished running and waiting for the next action). What are you trying to accomplish by running something on a page that a user isn’t viewing?

I’ve edited the message to clarify my use case: the main page includes calls to st.page and st.navigation that set up the second page as a subpage of the first. The ST docs suggest this works almost like template inclusion - where one template sets up the overall look of the website, and another formats the main content. What I’m trying to do is to have the main page run all of the code that is shared between subpages - including the OpenCV loop - and have one of those subpages display the output in real time. The problem is, that subpage only gets to run once before the loop starts, and then nothing else gets updated until it finishes. In a “regular” async context I could call asyncio.sleep(0) inside the loop to force a thread switch and allow the subpage to refresh; but ST has its own control flow, so I don’t think it’ll work here.