Introduction
This project shows you how to build a video player web app using Python and Streamlit. Users can upload any video file directly in the browser and watch it with built-in playback controls — no extra software required. Prefer audio instead? The same layout pattern drives the Streamlit music player.
🎬 Watch the Full Video Tutorial:
Watch the walkthrough on YouTube: TOP Python PRO Shares Video Player SECRETS Using Streamlit
Prerequisites
- Python 3.8+ — python.org
- Streamlit:
pip install streamlit
Step 1: Create the Script
Create video_player.py and paste the following:
import streamlit as st
st.set_page_config(page_title="Video Player", page_icon="🎬")
st.title("🎬 Video Player")
st.write("Upload a video file to play it directly in your browser.")
uploaded_file = st.file_uploader(
"Choose a video file",
type=["mp4", "mov", "avi", "mkv", "webm"]
)
if uploaded_file is not None:
file_details = {
"File Name": uploaded_file.name,
"File Size": f"{uploaded_file.size / (1024 * 1024):.2f} MB",
"File Type": uploaded_file.type,
}
st.subheader("📋 File Information")
for key, value in file_details.items():
st.write(f"**{key}:** {value}")
st.subheader("▶️ Now Playing")
st.video(uploaded_file)
st.success("Video loaded! Use the player controls to play, pause, or seek.")
else:
st.info("Please upload a video file to get started.")
Step 2: Run the App
streamlit run video_player.py
Step 3: Use the Video Player
Open the app in your browser, click Browse files, and select a video. The file info panel and video player appear instantly below.
How It Works
Streamlit ships st.video() as a native media element: pass it a file path or bytes and it renders an HTML5 player with play/pause/seek — no JavaScript required. The interesting engineering is around the player, not inside it.
Uploads arrive through st.file_uploader() as an in-memory UploadedFile. Because browsers only natively play MP4 (H.264), WebM, and Ogg, the app uses OpenCV to inspect the file and warns on unsupported containers rather than failing silently. That validation step — check the extension, peek at the codec with cv2.VideoCapture, then hand off to the player — is the difference between a demo and a tool people can actually use.
For large files, remember that everything streams through the browser on each rerun. Keeping the player as the only element on its rerun path (and caching anything expensive) keeps the app responsive.
Key Concepts
st.file_uploader()— Creates a drag-and-drop upload widget with file-type filtering.st.video()— Renders a native HTML5 video player for the uploaded file.uploaded_file.size— Returns file size in bytes (divide by 1,048,576 for MB).uploaded_file.type— Returns the MIME type, e.g.video/mp4.
Supported Formats
| Format | Extension | Notes |
|---|---|---|
| MP4 | .mp4 | Most common, best browser support |
| WebM | .webm | Open format, great for the web |
| MOV | .mov | Apple QuickTime format |
| AVI | .avi | Windows Media format |
| MKV | .mkv | Matroska container |
What to Try Next
- Extract and show a thumbnail from the first frame using OpenCV.
- Let users trim the video by specifying start/end times.
- Allow side-by-side comparison of two uploaded videos.
Common Errors & Fixes
-
Video uploads but shows a black screen — the codec is unsupported (common with .mov from iPhones). Re-encode with
ffmpeg -i in.mov -vcodec h264 out.mp4. -
st.videorejects the UploadedFile object — pass its bytes:st.video(uploaded.getvalue()). -
App freezes on big files — the file is being re-read on every rerun. Read once, store in
st.session_state. -
No sound in the player — the audio track uses a codec browsers skip (e.g. AC3). Re-encode audio to AAC alongside H.264 video.
FAQ
Which formats work in the browser?
MP4/H.264 is the safest choice, with WebM and Ogg also widely supported. AVI, MKV, and MOV usually need re-encoding.
Can I stream YouTube videos instead?
Not with st.video() directly — it plays direct media URLs. You would need streamlit-player style components or an embedded iframe.
How do I add a playlist?
Store selected files in st.session_state["queue"] and render an st.selectbox above the player — the same state pattern the quiz app uses for questions.
Can I generate a thumbnail from the video?
Yes — read a frame with OpenCV (cap.read()), convert BGR to RGB, and display it with st.image; the capture loop is the same one used for codec validation.