Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -2,25 +2,28 @@ import streamlit as st
|
|
2 |
from phi.agent import Agent
|
3 |
from phi.model.google import Gemini
|
4 |
from phi.tools.duckduckgo import DuckDuckGo
|
5 |
-
from phi.tools.youtube_tools import YouTubeTools
|
6 |
-
from google.generativeai import upload_file, get_file
|
7 |
import google.generativeai as genai
|
8 |
-
|
9 |
import time
|
10 |
from pathlib import Path
|
11 |
import tempfile
|
12 |
from dotenv import load_dotenv
|
13 |
-
load_dotenv()
|
14 |
-
|
15 |
import os
|
16 |
|
|
|
|
|
|
|
|
|
17 |
API_KEY = os.getenv("GOOGLE_API_KEY")
|
18 |
-
if API_KEY:
|
19 |
-
|
|
|
|
|
|
|
20 |
|
21 |
# Page configuration
|
22 |
st.set_page_config(
|
23 |
-
page_title="Multimodal AI Agent- Video Summarizer",
|
24 |
page_icon="π₯",
|
25 |
layout="wide"
|
26 |
)
|
@@ -34,7 +37,7 @@ def initialize_agent():
|
|
34 |
return Agent(
|
35 |
name="Video AI Summarizer",
|
36 |
model=Gemini(id="gemini-2.0-flash-exp"),
|
37 |
-
tools=[DuckDuckGo(), YouTubeTools()],
|
38 |
markdown=True,
|
39 |
)
|
40 |
|
@@ -47,91 +50,115 @@ user_query = st.text_area(
|
|
47 |
help="Provide specific questions or insights you want from the video."
|
48 |
)
|
49 |
|
50 |
-
#
|
51 |
-
|
52 |
-
"Upload a video file", type=['mp4', 'mov', 'avi'], help="Upload a video for AI analysis"
|
53 |
-
)
|
54 |
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
Analyze the {video_source} for content and context.
|
62 |
-
Respond to the following query using video insights and supplementary web research:
|
63 |
-
{user_query}
|
64 |
-
Provide a detailed, user-friendly, and actionable response.
|
65 |
-
"""
|
66 |
)
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
# Process uploaded video
|
69 |
if video_file:
|
70 |
-
with
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
# Process YouTube URL
|
105 |
-
|
106 |
-
|
107 |
-
if
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
st.info("Upload a video file or paste a YouTube URL to begin analysis.")
|
127 |
-
|
128 |
-
# Customize text area height
|
129 |
st.markdown(
|
130 |
"""
|
131 |
<style>
|
132 |
.stTextArea textarea {
|
133 |
height: 100px;
|
134 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
</style>
|
136 |
""",
|
137 |
unsafe_allow_html=True
|
|
|
2 |
from phi.agent import Agent
|
3 |
from phi.model.google import Gemini
|
4 |
from phi.tools.duckduckgo import DuckDuckGo
|
5 |
+
from phi.tools.youtube_tools import YouTubeTools
|
|
|
6 |
import google.generativeai as genai
|
|
|
7 |
import time
|
8 |
from pathlib import Path
|
9 |
import tempfile
|
10 |
from dotenv import load_dotenv
|
|
|
|
|
11 |
import os
|
12 |
|
13 |
+
# Load environment variables
|
14 |
+
load_dotenv()
|
15 |
+
|
16 |
+
# Configure Gemini API
|
17 |
API_KEY = os.getenv("GOOGLE_API_KEY")
|
18 |
+
if not API_KEY:
|
19 |
+
st.error("Please set the GOOGLE_API_KEY environment variable")
|
20 |
+
st.stop()
|
21 |
+
|
22 |
+
genai.configure(api_key=API_KEY)
|
23 |
|
24 |
# Page configuration
|
25 |
st.set_page_config(
|
26 |
+
page_title="Multimodal AI Agent - Video Summarizer",
|
27 |
page_icon="π₯",
|
28 |
layout="wide"
|
29 |
)
|
|
|
37 |
return Agent(
|
38 |
name="Video AI Summarizer",
|
39 |
model=Gemini(id="gemini-2.0-flash-exp"),
|
40 |
+
tools=[DuckDuckGo(), YouTubeTools()],
|
41 |
markdown=True,
|
42 |
)
|
43 |
|
|
|
50 |
help="Provide specific questions or insights you want from the video."
|
51 |
)
|
52 |
|
53 |
+
# Create tabs for different input methods
|
54 |
+
video_tab, youtube_tab = st.tabs(["Upload Video", "YouTube URL"])
|
|
|
|
|
55 |
|
56 |
+
with video_tab:
|
57 |
+
video_file = st.file_uploader(
|
58 |
+
"Upload a video file",
|
59 |
+
type=['mp4', 'mov', 'avi'],
|
60 |
+
help="Upload a video for AI analysis"
|
61 |
+
)
|
62 |
|
63 |
+
with youtube_tab:
|
64 |
+
youtube_url = st.text_input(
|
65 |
+
"Paste a YouTube URL:",
|
66 |
+
placeholder="https://www.youtube.com/watch?v=..."
|
|
|
|
|
|
|
|
|
|
|
67 |
)
|
68 |
|
69 |
+
def generate_analysis_prompt(user_query, video_source):
|
70 |
+
return f"""
|
71 |
+
Analyze the {video_source} for content and context.
|
72 |
+
Key areas to address:
|
73 |
+
1. Main topics and themes
|
74 |
+
2. Key points and insights
|
75 |
+
3. Specific answer to user query: {user_query}
|
76 |
+
4. Supporting context from web research
|
77 |
+
|
78 |
+
Provide a structured, detailed response with clear sections and actionable insights.
|
79 |
+
"""
|
80 |
+
|
81 |
# Process uploaded video
|
82 |
if video_file:
|
83 |
+
with video_tab:
|
84 |
+
st.video(video_file, format="video/mp4", start_time=0)
|
85 |
+
|
86 |
+
if st.button("π Analyze Uploaded Video", use_container_width=True):
|
87 |
+
if not user_query:
|
88 |
+
st.warning("Please enter a question or insight to analyze the video.")
|
89 |
+
else:
|
90 |
+
try:
|
91 |
+
with st.spinner("Processing video and gathering insights..."):
|
92 |
+
# Create temporary file
|
93 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as temp_video:
|
94 |
+
temp_video.write(video_file.getvalue())
|
95 |
+
video_path = temp_video.name
|
96 |
+
|
97 |
+
# Upload and process video
|
98 |
+
processed_video = genai.upload_file(video_path)
|
99 |
+
|
100 |
+
# Wait for processing with timeout
|
101 |
+
timeout = 60 # 60 seconds timeout
|
102 |
+
start_time = time.time()
|
103 |
+
while processed_video.state.name == "PROCESSING":
|
104 |
+
if time.time() - start_time > timeout:
|
105 |
+
raise TimeoutError("Video processing timed out")
|
106 |
+
time.sleep(1)
|
107 |
+
processed_video = genai.get_file(processed_video.name)
|
108 |
+
|
109 |
+
# Generate and run analysis
|
110 |
+
analysis_prompt = generate_analysis_prompt(user_query, "uploaded video")
|
111 |
+
response = multimodal_Agent.run(analysis_prompt, videos=[processed_video])
|
112 |
+
|
113 |
+
# Display results
|
114 |
+
st.success("Analysis complete!")
|
115 |
+
st.subheader("Analysis Results")
|
116 |
+
st.markdown(response.content)
|
117 |
+
|
118 |
+
except TimeoutError:
|
119 |
+
st.error("Video processing timed out. Please try with a shorter video.")
|
120 |
+
except Exception as error:
|
121 |
+
st.error(f"An error occurred: {str(error)}")
|
122 |
+
finally:
|
123 |
+
# Clean up temporary file
|
124 |
+
Path(video_path).unlink(missing_ok=True)
|
125 |
|
126 |
# Process YouTube URL
|
127 |
+
if youtube_url:
|
128 |
+
with youtube_tab:
|
129 |
+
if st.button("π Analyze YouTube Video", use_container_width=True):
|
130 |
+
if not user_query:
|
131 |
+
st.warning("Please enter a question or insight to analyze the video.")
|
132 |
+
else:
|
133 |
+
try:
|
134 |
+
with st.spinner("Fetching video content and analyzing..."):
|
135 |
+
# Generate and run analysis
|
136 |
+
analysis_prompt = generate_analysis_prompt(user_query, "YouTube video")
|
137 |
+
response = multimodal_Agent.run(analysis_prompt, youtube_url=youtube_url)
|
138 |
+
|
139 |
+
# Display results
|
140 |
+
st.success("Analysis complete!")
|
141 |
+
st.subheader("Analysis Results")
|
142 |
+
st.markdown(response.content)
|
143 |
+
|
144 |
+
except Exception as error:
|
145 |
+
st.error(f"An error occurred: {str(error)}")
|
146 |
+
|
147 |
+
# Custom styling
|
|
|
|
|
|
|
148 |
st.markdown(
|
149 |
"""
|
150 |
<style>
|
151 |
.stTextArea textarea {
|
152 |
height: 100px;
|
153 |
}
|
154 |
+
.stButton button {
|
155 |
+
background-color: #FF4B4B;
|
156 |
+
color: white;
|
157 |
+
font-weight: bold;
|
158 |
+
}
|
159 |
+
.stButton button:hover {
|
160 |
+
background-color: #FF3333;
|
161 |
+
}
|
162 |
</style>
|
163 |
""",
|
164 |
unsafe_allow_html=True
|