Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -25,52 +25,8 @@ if 'processed_data' not in st.session_state:
|
|
25 |
if 'image_data' not in st.session_state:
|
26 |
st.session_state.image_data = None
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
return """
|
31 |
-
<div id="timer" style="font-size:16px;color:#666;margin-bottom:10px;">⏱️ Elapsed: 00:00</div>
|
32 |
-
<script>
|
33 |
-
var timerInterval;
|
34 |
-
|
35 |
-
function updateTimer() {
|
36 |
-
var start = Date.now();
|
37 |
-
var timerElement = document.getElementById('timer');
|
38 |
-
|
39 |
-
timerInterval = setInterval(function() {
|
40 |
-
var elapsed = Date.now() - start;
|
41 |
-
var minutes = Math.floor(elapsed / 60000);
|
42 |
-
var seconds = Math.floor((elapsed % 60000) / 1000);
|
43 |
-
timerElement.innerHTML = '⏱️ Elapsed: ' +
|
44 |
-
(minutes < 10 ? '0' : '') + minutes + ':' +
|
45 |
-
(seconds < 10 ? '0' : '') + seconds;
|
46 |
-
}, 1000);
|
47 |
-
}
|
48 |
-
|
49 |
-
function stopTimer() {
|
50 |
-
if (timerInterval) {
|
51 |
-
clearInterval(timerInterval);
|
52 |
-
document.getElementById('timer').style.color = '#00cc00';
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
updateTimer();
|
57 |
-
|
58 |
-
// Handle Streamlit's component cleanup
|
59 |
-
window.addEventListener('beforeunload', function() {
|
60 |
-
if (timerInterval) clearInterval(timerInterval);
|
61 |
-
});
|
62 |
-
</script>
|
63 |
-
"""
|
64 |
-
|
65 |
-
# Stop timer function
|
66 |
-
def stop_timer():
|
67 |
-
html("""
|
68 |
-
<script>
|
69 |
-
if (typeof stopTimer === 'function') {
|
70 |
-
stopTimer();
|
71 |
-
}
|
72 |
-
</script>
|
73 |
-
""", height=0)
|
74 |
|
75 |
# Page setup
|
76 |
st.set_page_config(page_title="Your Image to Audio Story", page_icon="🦜")
|
@@ -111,38 +67,109 @@ def text2audio(story_text):
|
|
111 |
audio_io.seek(0)
|
112 |
return {'audio': audio_io, 'sampling_rate': 16000}
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
# UI components
|
115 |
uploaded_file = st.file_uploader("Select an Image After the Models are Loaded...")
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
if uploaded_file is not None:
|
118 |
# Save the image data to session state
|
119 |
bytes_data = uploaded_file.getvalue()
|
120 |
st.session_state.image_data = bytes_data
|
121 |
|
122 |
-
#
|
123 |
-
|
124 |
-
progress_bar = st.progress(0)
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
#
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
140 |
# Stage 1: Image to Text
|
141 |
status_text.markdown("**🖼️ Generating caption...**")
|
142 |
progress_bar.progress(0)
|
143 |
st.session_state.processed_data['scenario'] = img2text(uploaded_file.name)
|
144 |
progress_bar.progress(33)
|
145 |
-
|
146 |
# Stage 2: Text to Story
|
147 |
status_text.markdown("**📖 Generating story...**")
|
148 |
progress_bar.progress(33)
|
@@ -150,7 +177,7 @@ if uploaded_file is not None:
|
|
150 |
st.session_state.processed_data['scenario']
|
151 |
)
|
152 |
progress_bar.progress(66)
|
153 |
-
|
154 |
# Stage 3: Story to Audio
|
155 |
status_text.markdown("**🔊 Synthesizing audio...**")
|
156 |
progress_bar.progress(66)
|
@@ -158,38 +185,31 @@ if uploaded_file is not None:
|
|
158 |
st.session_state.processed_data['story']
|
159 |
)
|
160 |
progress_bar.progress(100)
|
161 |
-
|
162 |
-
# Final status
|
163 |
status_text.success("**✅ Generation complete!**")
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
elif st.session_state.image_data is not None:
|
180 |
-
# Display the previously uploaded image from session state
|
181 |
-
st.image(st.session_state.image_data, caption="Uploaded Image", use_container_width=True)
|
182 |
-
|
183 |
-
# Show previous results if available
|
184 |
-
if st.session_state.processed_data.get('scenario'):
|
185 |
-
st.write("**Caption:**", st.session_state.processed_data['scenario'])
|
186 |
-
if st.session_state.processed_data.get('story'):
|
187 |
-
st.write("**Story:**", st.session_state.processed_data['story'])
|
188 |
-
|
189 |
|
190 |
# Audio playback
|
191 |
if st.button("Play Audio of the Story Generated"):
|
192 |
if st.session_state.processed_data.get('audio'):
|
|
|
|
|
|
|
|
|
193 |
audio_data = st.session_state.processed_data['audio']
|
194 |
st.audio(
|
195 |
audio_data['audio'].getvalue(),
|
|
|
25 |
if 'image_data' not in st.session_state:
|
26 |
st.session_state.image_data = None
|
27 |
|
28 |
+
if 'timer_active' not in st.session_state:
|
29 |
+
st.session_state.timer_active = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
# Page setup
|
32 |
st.set_page_config(page_title="Your Image to Audio Story", page_icon="🦜")
|
|
|
67 |
audio_io.seek(0)
|
68 |
return {'audio': audio_io, 'sampling_rate': 16000}
|
69 |
|
70 |
+
# Create fixed containers for UI elements
|
71 |
+
image_container = st.empty()
|
72 |
+
timer_container = st.empty()
|
73 |
+
status_container = st.empty()
|
74 |
+
progress_container = st.empty()
|
75 |
+
results_container = st.container()
|
76 |
+
|
77 |
+
# JavaScript timer component with stop function
|
78 |
+
def create_timer():
|
79 |
+
return """
|
80 |
+
<div id="timer-container">
|
81 |
+
<div id="timer" style="font-size:16px;color:#666;margin-bottom:10px;">⏱️ Elapsed: 00:00</div>
|
82 |
+
</div>
|
83 |
+
<script>
|
84 |
+
// Create a unique timer ID for this session
|
85 |
+
const timerID = 'timer-' + Date.now();
|
86 |
+
window[timerID] = null;
|
87 |
+
|
88 |
+
function startTimer() {
|
89 |
+
// Clear any existing timer
|
90 |
+
if (window[timerID]) {
|
91 |
+
clearInterval(window[timerID]);
|
92 |
+
}
|
93 |
+
|
94 |
+
const start = Date.now();
|
95 |
+
const timerElement = document.getElementById('timer');
|
96 |
+
|
97 |
+
window[timerID] = setInterval(function() {
|
98 |
+
const elapsed = Date.now() - start;
|
99 |
+
const minutes = Math.floor(elapsed / 60000);
|
100 |
+
const seconds = Math.floor((elapsed % 60000) / 1000);
|
101 |
+
timerElement.innerHTML = '⏱️ Elapsed: ' +
|
102 |
+
(minutes < 10 ? '0' : '') + minutes + ':' +
|
103 |
+
(seconds < 10 ? '0' : '') + seconds;
|
104 |
+
}, 1000);
|
105 |
+
}
|
106 |
+
|
107 |
+
// Start the timer immediately
|
108 |
+
startTimer();
|
109 |
+
|
110 |
+
// Expose the timer ID so it can be stopped later
|
111 |
+
window.currentTimerID = timerID;
|
112 |
+
</script>
|
113 |
+
"""
|
114 |
+
|
115 |
+
def stop_timer():
|
116 |
+
return """
|
117 |
+
<script>
|
118 |
+
if (window.currentTimerID && window[window.currentTimerID]) {
|
119 |
+
clearInterval(window[window.currentTimerID]);
|
120 |
+
window[window.currentTimerID] = null;
|
121 |
+
document.getElementById('timer').style.color = '#00cc00';
|
122 |
+
}
|
123 |
+
</script>
|
124 |
+
"""
|
125 |
+
|
126 |
# UI components
|
127 |
uploaded_file = st.file_uploader("Select an Image After the Models are Loaded...")
|
128 |
+
|
129 |
+
# Always display the image if we have image data
|
130 |
+
if st.session_state.image_data is not None:
|
131 |
+
image_container.image(st.session_state.image_data, caption="Uploaded Image", use_container_width=True)
|
132 |
+
|
133 |
+
# Display results if available
|
134 |
+
if st.session_state.processed_data.get('scenario'):
|
135 |
+
with results_container:
|
136 |
+
st.write("**Caption:**", st.session_state.processed_data['scenario'])
|
137 |
+
|
138 |
+
if st.session_state.processed_data.get('story'):
|
139 |
+
with results_container:
|
140 |
+
st.write("**Story:**", st.session_state.processed_data['story'])
|
141 |
+
|
142 |
+
# Process new uploaded file
|
143 |
if uploaded_file is not None:
|
144 |
# Save the image data to session state
|
145 |
bytes_data = uploaded_file.getvalue()
|
146 |
st.session_state.image_data = bytes_data
|
147 |
|
148 |
+
# Display the image
|
149 |
+
image_container.image(bytes_data, caption="Uploaded Image", use_container_width=True)
|
|
|
150 |
|
151 |
+
if st.session_state.get('current_file') != uploaded_file.name:
|
152 |
+
st.session_state.current_file = uploaded_file.name
|
153 |
+
st.session_state.timer_active = True
|
154 |
+
|
155 |
+
# Display timer
|
156 |
+
timer_container.html(create_timer(), height=60)
|
157 |
+
|
158 |
+
# Progress indicators
|
159 |
+
status_text = status_container.empty()
|
160 |
+
progress_bar = progress_container.progress(0)
|
161 |
+
|
162 |
+
try:
|
163 |
+
# Save uploaded file
|
164 |
+
with open(uploaded_file.name, "wb") as file:
|
165 |
+
file.write(bytes_data)
|
166 |
+
|
167 |
# Stage 1: Image to Text
|
168 |
status_text.markdown("**🖼️ Generating caption...**")
|
169 |
progress_bar.progress(0)
|
170 |
st.session_state.processed_data['scenario'] = img2text(uploaded_file.name)
|
171 |
progress_bar.progress(33)
|
172 |
+
|
173 |
# Stage 2: Text to Story
|
174 |
status_text.markdown("**📖 Generating story...**")
|
175 |
progress_bar.progress(33)
|
|
|
177 |
st.session_state.processed_data['scenario']
|
178 |
)
|
179 |
progress_bar.progress(66)
|
180 |
+
|
181 |
# Stage 3: Story to Audio
|
182 |
status_text.markdown("**🔊 Synthesizing audio...**")
|
183 |
progress_bar.progress(66)
|
|
|
185 |
st.session_state.processed_data['story']
|
186 |
)
|
187 |
progress_bar.progress(100)
|
188 |
+
|
189 |
+
# Final status
|
190 |
status_text.success("**✅ Generation complete!**")
|
191 |
+
|
192 |
+
# Stop timer
|
193 |
+
timer_container.html(stop_timer(), height=0)
|
194 |
+
|
195 |
+
# Show results
|
196 |
+
with results_container:
|
197 |
+
st.write("**Caption:**", st.session_state.processed_data['scenario'])
|
198 |
+
st.write("**Story:**", st.session_state.processed_data['story'])
|
199 |
+
|
200 |
+
except Exception as e:
|
201 |
+
timer_container.html(stop_timer(), height=0)
|
202 |
+
status_text.error(f"**❌ Error:** {str(e)}")
|
203 |
+
progress_bar.empty()
|
204 |
+
raise e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
# Audio playback
|
207 |
if st.button("Play Audio of the Story Generated"):
|
208 |
if st.session_state.processed_data.get('audio'):
|
209 |
+
# Make sure the image is still displayed
|
210 |
+
if st.session_state.image_data is not None:
|
211 |
+
image_container.image(st.session_state.image_data, caption="Uploaded Image", use_container_width=True)
|
212 |
+
|
213 |
audio_data = st.session_state.processed_data['audio']
|
214 |
st.audio(
|
215 |
audio_data['audio'].getvalue(),
|