Update app.py
Browse files
app.py
CHANGED
@@ -3,6 +3,9 @@ from colab import AIDancePartner
|
|
3 |
import tempfile
|
4 |
import os
|
5 |
import time
|
|
|
|
|
|
|
6 |
|
7 |
# Set page configuration
|
8 |
st.set_page_config(
|
@@ -52,6 +55,18 @@ def local_css():
|
|
52 |
</style>
|
53 |
""", unsafe_allow_html=True)
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
def main():
|
56 |
local_css()
|
57 |
|
@@ -70,6 +85,23 @@ def main():
|
|
70 |
st.markdown('<p class="upload-text">Upload your dance video and watch the magic happen!</p>', unsafe_allow_html=True)
|
71 |
uploaded_file = st.file_uploader("", type=['mp4', 'avi', 'mov'])
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
with col2:
|
74 |
st.markdown('<div class="info-box">', unsafe_allow_html=True)
|
75 |
st.markdown("### How it works")
|
@@ -80,54 +112,61 @@ def main():
|
|
80 |
""")
|
81 |
st.markdown('</div>', unsafe_allow_html=True)
|
82 |
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
with open(output_path, 'rb') as file:
|
132 |
st.download_button(
|
133 |
label="Download Your Dance Duet π₯",
|
@@ -135,21 +174,27 @@ def main():
|
|
135 |
file_name="ai_dance_partner.mp4",
|
136 |
mime="video/mp4"
|
137 |
)
|
138 |
-
|
139 |
-
|
140 |
-
os.unlink(temp_input_path)
|
141 |
-
os.unlink(output_path)
|
142 |
-
|
143 |
-
except Exception as e:
|
144 |
-
st.error(f"Oops! Something went wrong: {str(e)}")
|
145 |
-
if os.path.exists(temp_input_path):
|
146 |
os.unlink(temp_input_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
-
# Add footer
|
149 |
st.markdown("""
|
150 |
---
|
151 |
-
<div style="text-align: center;
|
152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
</div>
|
154 |
""", unsafe_allow_html=True)
|
155 |
|
|
|
3 |
import tempfile
|
4 |
import os
|
5 |
import time
|
6 |
+
import cv2
|
7 |
+
from PIL import Image
|
8 |
+
import io
|
9 |
|
10 |
# Set page configuration
|
11 |
st.set_page_config(
|
|
|
55 |
</style>
|
56 |
""", unsafe_allow_html=True)
|
57 |
|
58 |
+
def get_video_preview(video_path):
|
59 |
+
"""Generate a preview frame from the video"""
|
60 |
+
cap = cv2.VideoCapture(video_path)
|
61 |
+
ret, frame = cap.read()
|
62 |
+
cap.release()
|
63 |
+
|
64 |
+
if ret:
|
65 |
+
# Convert BGR to RGB
|
66 |
+
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
67 |
+
return Image.fromarray(frame)
|
68 |
+
return None
|
69 |
+
|
70 |
def main():
|
71 |
local_css()
|
72 |
|
|
|
85 |
st.markdown('<p class="upload-text">Upload your dance video and watch the magic happen!</p>', unsafe_allow_html=True)
|
86 |
uploaded_file = st.file_uploader("", type=['mp4', 'avi', 'mov'])
|
87 |
|
88 |
+
# Add video preview
|
89 |
+
if uploaded_file is not None:
|
90 |
+
# Create a temporary file for the uploaded video
|
91 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tfile:
|
92 |
+
tfile.write(uploaded_file.read())
|
93 |
+
temp_input_path = tfile.name
|
94 |
+
|
95 |
+
# Show video preview
|
96 |
+
st.markdown("### π½οΈ Preview")
|
97 |
+
preview_image = get_video_preview(temp_input_path)
|
98 |
+
if preview_image:
|
99 |
+
st.image(preview_image, use_column_width=True, caption="Video Preview")
|
100 |
+
|
101 |
+
# Add video player for original
|
102 |
+
st.markdown("### π₯ Original Video")
|
103 |
+
st.video(temp_input_path)
|
104 |
+
|
105 |
with col2:
|
106 |
st.markdown('<div class="info-box">', unsafe_allow_html=True)
|
107 |
st.markdown("### How it works")
|
|
|
112 |
""")
|
113 |
st.markdown('</div>', unsafe_allow_html=True)
|
114 |
|
115 |
+
if uploaded_file is not None:
|
116 |
+
# Style selection with custom design
|
117 |
+
st.markdown("### π Choose Your Dance Partner Style")
|
118 |
+
style = st.select_slider(
|
119 |
+
"",
|
120 |
+
options=["Sync Partner", "Creative Partner"],
|
121 |
+
value="Sync Partner"
|
122 |
+
)
|
123 |
+
|
124 |
+
# Add description based on selected style
|
125 |
+
if style == "Sync Partner":
|
126 |
+
st.info("π« Sync Partner will mirror your movements in perfect harmony.")
|
127 |
+
else:
|
128 |
+
st.info("π¨ Creative Partner will add its own artistic flair to your dance.")
|
129 |
+
|
130 |
+
if st.button("Generate Dance Partner π¬"):
|
131 |
+
try:
|
132 |
+
# Create a progress bar
|
133 |
+
progress_bar = st.progress(0)
|
134 |
+
status_text = st.empty()
|
135 |
+
|
136 |
+
# Processing steps with more detailed progress
|
137 |
+
steps = [
|
138 |
+
"Analyzing dance moves...",
|
139 |
+
"Detecting pose landmarks...",
|
140 |
+
"Generating partner movements...",
|
141 |
+
"Applying style patterns...",
|
142 |
+
"Creating final video..."
|
143 |
+
]
|
144 |
+
|
145 |
+
for i, step in enumerate(steps):
|
146 |
+
status_text.text(step)
|
147 |
+
progress_bar.progress((i + 1) * 20)
|
148 |
+
time.sleep(0.5)
|
149 |
+
|
150 |
+
# Process video
|
151 |
+
dance_partner = AIDancePartner()
|
152 |
+
output_path = dance_partner.process_video(temp_input_path, mode=style)
|
153 |
+
|
154 |
+
# Update progress
|
155 |
+
progress_bar.progress(100)
|
156 |
+
status_text.text("Done! π")
|
157 |
+
|
158 |
+
# Display result in a nice container
|
159 |
+
st.markdown("### π₯ Your Dance Duet")
|
160 |
+
|
161 |
+
# Show preview of the output
|
162 |
+
preview_output = get_video_preview(output_path)
|
163 |
+
if preview_output:
|
164 |
+
st.image(preview_output, use_column_width=True, caption="Dance Duet Preview")
|
165 |
+
|
166 |
+
# Display the video
|
167 |
+
st.video(output_path)
|
168 |
+
|
169 |
+
# Download button with custom styling
|
170 |
with open(output_path, 'rb') as file:
|
171 |
st.download_button(
|
172 |
label="Download Your Dance Duet π₯",
|
|
|
174 |
file_name="ai_dance_partner.mp4",
|
175 |
mime="video/mp4"
|
176 |
)
|
177 |
+
|
178 |
+
# Cleanup temporary files
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
os.unlink(temp_input_path)
|
180 |
+
os.unlink(output_path)
|
181 |
+
|
182 |
+
except Exception as e:
|
183 |
+
st.error(f"Oops! Something went wrong: {str(e)}")
|
184 |
+
if os.path.exists(temp_input_path):
|
185 |
+
os.unlink(temp_input_path)
|
186 |
|
187 |
+
# Add footer with additional information
|
188 |
st.markdown("""
|
189 |
---
|
190 |
+
<div style="text-align: center;">
|
191 |
+
<h3>π Features</h3>
|
192 |
+
<p>β’ Real-time pose detection</p>
|
193 |
+
<p>β’ Synchronized movement matching</p>
|
194 |
+
<p>β’ Creative dance style generation</p>
|
195 |
+
<p>β’ High-quality video output</p>
|
196 |
+
<br>
|
197 |
+
<p style="color: #666;">Made with β€οΈ by AI Dance Partner Team</p>
|
198 |
</div>
|
199 |
""", unsafe_allow_html=True)
|
200 |
|