Mayankuttam's picture
Create app.py
4a7fda3 verified
import streamlit as st
import tempfile
import os
from model_pipeline import run_model_on_video # Assuming this function exists and is correctly implemented
# Page setup
st.set_page_config(
page_title="AI Cricket Commentary",
layout="wide",
initial_sidebar_state="collapsed",
menu_items={
'Get Help': 'https://www.example.com/help',
'Report a bug': "https://www.example.com/bug",
'About': "# AI Cricket Commentary Generator"
}
)
# Custom CSS for a professional, dark theme look
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
html, body, .stApp {
background-color: #0d0e12;
font-family: 'Inter', sans-serif;
color: #e0e0e0;
}
.main-title {
font-size: 2.5rem;
font-weight: 700;
color: #e0e0e0;
text-align: center;
margin-top: 1rem;
margin-bottom: 0.2rem;
display: flex;
justify-content: center;
align-items: center;
gap: 0.75rem;
}
.subtitle {
font-size: 1.1rem;
color: #a0a0a0;
font-weight: 400;
text-align: center;
margin-bottom: 2rem;
}
.section-header {
font-size: 1.5rem;
font-weight: 600;
color: #e0e0e0;
margin-top: 3rem;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
/* Main container for the "Try It Yourself" section to fix alignment */
.main-content-container {
display: flex;
justify-content: space-between;
gap: 2rem;
margin-bottom: 2rem;
}
/* Custom file uploader styling to match the image */
.stFileUploader {
background: #1f2229;
border: 2px dashed #444a56;
padding: 1.5rem;
border-radius: 12px;
text-align: center;
cursor: pointer;
transition: border-color 0.3s ease, background 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.stFileUploader:hover {
border-color: #6a6f7b;
background: #282b33;
}
.stFileUploader [data-testid="stFileUploaderDropzone"] {
background: transparent !important;
border: none !important;
padding: 0 !important;
}
.stFileUploader [data-testid="stFileUploaderFile"] {
background-color: #2c2e36;
color: #e0e0e0;
border-radius: 8px;
padding: 0.5rem;
margin-top: 1rem;
}
.stFileUploader [data-testid="stFileUploaderDropzone"] [data-testid="stMarkdownContainer"] {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.stFileUploader [data-testid="stMarkdownContainer"] p:first-child {
font-size: 1rem;
font-weight: 600;
color: #e0e0e0;
margin-bottom: 0.25rem;
}
.stFileUploader [data-testid="stMarkdownContainer"] p:nth-child(2) {
font-size: 0.8rem;
color: #7b7d85;
}
/* Uploaded video display */
.stVideo {
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.video-container, .results-box {
background: #1f2229;
padding: 1.5rem;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
height: 100%;
border: 1px solid #2c2f37;
}
.results-box h3 {
margin-top: 0;
color: #e0e0e0;
}
.results-box .placeholder-text {
color: #7b7d85;
text-align: center;
padding-top: 2rem;
padding-bottom: 2rem;
}
/* Button styling */
.stButton>button {
background: #007bff;
color: white;
font-weight: 600;
border-radius: 8px;
padding: 0.75rem 1.5rem;
border: none;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 123, 255, 0.2);
}
.stButton>button:hover {
background: #0056b3;
transform: translateY(-2px);
box-shadow: 0 6px 10px rgba(0, 123, 255, 0.3);
}
.stDownloadButton>button {
background: #444a56;
color: #e0e0e0;
font-weight: 600;
border: none;
border-radius: 8px;
padding: 0.75rem 1.5rem;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
}
.stDownloadButton>button:hover {
background: #5d616d;
transform: translateY(-2px);
box-shadow: 0 6px 10px rgba(0,0,0,0.3);
}
/* Footer styling */
.footer {
text-align: center;
font-size: 0.9rem;
color: #7b7d85;
margin-top: 5rem;
padding-top: 2rem;
border-top: 1px solid #2c2f37;
}
</style>
""", unsafe_allow_html=True)
# --- HEADER ---
st.markdown('<h1 class="main-title">🏏 AI Cricket Commentary Generator</h1>', unsafe_allow_html=True)
st.markdown('<p class="subtitle">Revolutionizing Cricket Commentary with AI-driven analysis</p>', unsafe_allow_html=True)
# --- TRY IT YOURSELF SECTION ---
st.markdown('<h2 class="section-header">🎬 Try It Yourself</h2>', unsafe_allow_html=True)
# Use st.columns to create a clean two-column layout for upload and commentary
col_upload, col_display = st.columns(2)
with col_upload:
st.markdown("<h4>Upload Cricket Match Video</h4>", unsafe_allow_html=True)
video_file = st.file_uploader(
"Drag and drop file here\nLimit 200MB per file",
type=["mp4", "mov", "avi", "mpeg4"],
label_visibility="collapsed"
)
with col_display:
if video_file:
st.markdown("<h4>Uploaded Video Preview</h4>", unsafe_allow_html=True)
st.video(video_file)
if st.button("πŸš€ Generate Commentary", use_container_width=True):
with st.spinner("Generating... please wait ⏳"):
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp:
tmp.write(video_file.read())
temp_video_path = tmp.name
try:
commentary_text, audio_path, video_output_path = run_model_on_video(temp_video_path)
st.success("βœ… Commentary Generated Successfully!")
st.markdown(f"**πŸ“ AI Commentary Summary:**\n\n{commentary_text}")
st.audio(audio_path, format="audio/mp3", autoplay=False)
col_audio, col_video = st.columns(2)
with col_audio:
with open(audio_path, 'rb') as a:
st.download_button("⬇️ Download Audio", a, file_name="commentary.mp3", use_container_width=True)
with col_video:
with open(video_output_path, 'rb') as v:
st.download_button("⬇️ Download Final Video", v, file_name="final_video.mp4", use_container_width=True)
st.video(video_output_path)
except Exception as e:
st.error(f"❌ An error occurred: {e}")
st.exception(e)
finally:
try:
if 'temp_video_path' in locals() and os.path.exists(temp_video_path):
os.remove(temp_video_path)
if 'audio_path' in locals() and os.path.exists(audio_path):
os.remove(audio_path)
if 'video_output_path' in locals() and os.path.exists(video_output_path):
os.remove(video_output_path)
except PermissionError:
st.warning("Could not delete temporary files. Please delete them manually if necessary.")
else:
st.markdown('<div class="results-box">', unsafe_allow_html=True)
st.markdown("<h3>AI Generated Commentary</h3>", unsafe_allow_html=True)
st.markdown('<p class="placeholder-text">Upload a cricket video to see the preview and generate commentary.</p>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# --- HOW IT WORKS SECTION ---
st.markdown('<div class="section-header">βš™οΈ How It Works</div>', unsafe_allow_html=True)
how_cols = st.columns(3)
steps = [
("πŸ“€ Upload Video", "Upload your cricket video file. Our system processes it frame by frame."),
("🧠 AI Analysis", "The AI analyzes key events, recognizes shots, and predicts outcomes."),
("πŸ—£οΈ Generate Commentary", "High-quality, professional commentary is generated and ready for playback or download.")
]
for col, (title, desc) in zip(how_cols, steps):
with col:
st.markdown(f'<div class="results-box"><h4>{title}</h4><p>{desc}</p></div>', unsafe_allow_html=True)
# --- KEY FEATURES SECTION ---
st.markdown('<div class="section-header">⭐ Key Features</div>', unsafe_allow_html=True)
feature_cols = st.columns(3)
features = [
("🎯 Shot Recognition", "Accurately detects shots like cover drives, sweeps, pulls, and hooks."),
("πŸ“Š Outcome Prediction", "Intelligently predicts boundaries, wickets, and other key outcomes."),
("πŸŽ™οΈ Broadcast-Quality Commentary", "Generates dynamic commentary using proper cricket terminology and flow."),
]
for col, (title, desc) in zip(feature_cols, features):
with col:
st.markdown(f'<div class="results-box"><h5>{title}</h5><p>{desc}</p></div>', unsafe_allow_html=True)
# --- FOOTER ---
st.markdown('<div class="footer">Made with ❀️ by AI Cricket Labs | © 2024</div>', unsafe_allow_html=True)