Displaying Multicast MPEG video using streamlit


I want a way to view a multicast MPEG TS stream in a streamlit app, preferably with a way to draw bounding boxes on the video

Steps to reproduce

Code snippet:

import streamlit as st
import subprocess
import numpy as np
st.title("Streaming Video Demo")
st.write("Paste ``ffmpeg -i \"data/day.mpg\" -map 0 -vcodec libx264 -f mpegts udp://`` in your terminal")
video_stream = st.text_input("MPEG TS Stream Address", value="udp://")
width = st.number_input("Width", min_value=0, max_value=4096, value=1280)
height = st.number_input("Height", min_value=0, max_value=4096, value=720)
video_stream_cmd = ['ffmpeg', '-i', f'{video_stream}?overrun_nonfatal=1', 
                    '-map', '0:0',  
                    '-f', 'image2pipe', 
                    '-pix_fmt', 'bgr24', 
                    '-codec', 'mp4', '-']
video = st.empty()
vid_proc = None
stream = st.checkbox("Start Stream")
while  stream :
    if vid_proc == None :
        vid_proc = subprocess.Popen(video_stream_cmd,stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        raw_frame = vid_proc.stdout.read(width*height*3) # reads raw video stream
        frame = np.frombuffer(raw_frame, np.uint8)
        frame = frame.reshape((height, width, 3))
        video.image(vid_proc.stdout, width=width)
    except ValueError: pass

Where data/day.mpg is http://samples.ffmpeg.org/MPEG2/mpegts-klv/Day%20Flight.mpg

I start the streamlit app, start the stream on a separate command line, and then click the checkbox to start the ffmpeg subprocess. I usually get a frame or two, but nothing close to a video stream. Clearly I am going about this the wrong way, but what might be a better solution?

Debug info

  • Streamlit version: 1.27.2
  • Python version: 3.8.18
  • OS version: python:3.8-bookworm Docker container
  • Browser version: Firefox 118.0.2

Requirements file

FROM python:3.8-bookworm
ENV DEBIAN_FRONTEND noninteractive
RUN apt update \
 && apt install -y ffmpeg 
RUN pip install --upgrade --no-cache pip wheel setuptools \
 && pip install --no-cache streamlit opencv-python-headless

COPY ./app.py /opt/streamlit/app.py

ENTRYPOINT ["streamlit"]
CMD ["run", "/opt/streamlit/app.py"]

Hi @shelbydavis,

Thanks for posting!

Have you considered using OpenCV? You could use FFmpeg to grab the stream and pipe it to OpenCV. OpenCV can handle the video decoding. Let me know if you’ve tried this.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.