How to access uploaded video in streamlit by open cv?

Hi, I want to upload video through streamlit and want to access it with cv.VideoCapture()
function. So How can i do please help me.

Hi @Pavan_Cheyutha, welcome to the Streamlit community!

When you upload a video through Streamlit, the Python variable you assign to the function call has your video in it in a BytesIO buffer. cv.VideoCapture does a similar thing, taking video from a video camera and saving it in a buffer.

So it’s unlikely that you need to pass a video from file_uploader to cv.VideoCapture(). What are you looking to do with the video after you upload it?

Hi, Thank you for your reply. I built a model with YOLOv3 for object detection purpose. As you said I used file_uploader. let me explain my problem clearly.

this is the code I worte:

video_file = st.file_uploader(‘video’, type = [‘mp4’])
cap = cv2.VideoCapture(video_file)

the type of video_file is BytesIO
, here VideoCapture() will take only URL path.
So, I think there is no solution for this problem.

But now I want this, —> if I upload a file, instead of file , file path should be uploaded. Is it possible in streamlit now.

Thank you

I guess my question is, why can’t you just remove this line of code? As long as you convert the buffer from video_file to the file format of cv2.VideoCapture, you’ll effectively have the same code.

For a web app, you generally don’t specify the directory name of a file, because the browser that is accessing the web app isn’t necessarily the same computer as the one running the code. So sending the bytes into a buffer is usually what is desired, because then the data is guaranteed to exist on the computer running the web app.

I am using open-cv, I have to read video, frame by frame, if I remove VideoCapture() How can I access video frame by frame.
It is like this;

Video --> Frame by Frame --> enter into Model --> model find the objects in frame and marks it with rectangle boxes --> display the output on the screen.

So can I use that BytesIO object as above?

Seems wasteful, but if OpenCV really requires a file, I wonder if this will be acceptable:

import streamlit as st
import cv2 as cv
import tempfile

f = st.file_uploader("Upload file")
tfile = tempfile.NamedTemporaryFile(delete=False)
tfile.write(f.read())
vf = cv.VideoCapture(tfile.name)

Super…….Thank you very much.

One more doubt, Open cv will play video in separate window, I want to play it in streamlit web app. Is it possible?

I tried but all frames are displayed in web app as images one by one.

Something like this should work. The key is defining st.empty() outside of the loop, then writing to the object from inside the loop:

import streamlit as st
import cv2 as cv
import tempfile

f = st.file_uploader("Upload file")

tfile = tempfile.NamedTemporaryFile(delete=False) 
tfile.write(f.read())


vf = cv.VideoCapture(tfile.name)

stframe = st.empty()

while vf.isOpened():
    ret, frame = vf.read()
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    stframe.image(gray)

I feeling very lucky to communicate with you. Surely I will implement that code and will let u know my out put. Thank you very much. I love the way u response and understanding the problem.

1 Like

Hey Hi, I implemented your code in my work it is working perfectly. Thank you very much.
I am going to develop on APP for to support my friend business, for that I want use Streamlit. So I need your support in future also. Thank you very much.

1 Like