I doubt that that really works for videos but I wish I’m wrong and the docs are right
I would encode the numpy array data using OpenCV
, then pass it to ffmpeg
to make the video compatible to the HTML5 player that streamlit uses (see this thread about the codec’s issue: Processing video with OpenCV and write it to disk (to display in st.video) - #2 by edsaac).
Code:
import numpy as np
import streamlit as st
import cv2
import subprocess
from tempfile import NamedTemporaryFile
height, width, n_frames = 360, 200, 30
frames_per_second = 12
# Generate some data
data = np.linspace(0, 256, height * width * n_frames, dtype=np.uint8).reshape(
n_frames, width, height
)
data[:, 50:100, 50:100] = 255 # A white square
"### `st.video(np.ndarray)`"
st.video(data) ## This will fail
temp_files_kwargs = dict(suffix=".mp4", dir=".")
with (
NamedTemporaryFile(**temp_files_kwargs) as temporal_video,
NamedTemporaryFile(**temp_files_kwargs) as converted_video,
):
out = cv2.VideoWriter(
temporal_video.name,
cv2.VideoWriter_fourcc(*"mp4v"),
frames_per_second,
(height, width),
False,
)
for frame in data:
out.write(frame)
out.release()
## Call ffmpeg to convert to a web-playable codec.
subprocess.call(
args=f"ffmpeg -y -i {temporal_video.name} -c:v libx264 {converted_video.name}".split(),
stdout=subprocess.DEVNULL,
)
## This will show a video
"""### `st.video("encoded_data.mp4")`"""
st.video(converted_video.name)
You will need ffmpeg (
apt install ffmpeg
) and OpenCV ( pip install opencv-python-headless
) installed.