Update app.py
Browse files
app.py
CHANGED
@@ -226,8 +226,12 @@ async def async_edge_tts_generate(text, voice, username, rate=0, pitch=0, file_f
|
|
226 |
try:
|
227 |
communicate = edge_tts.Communicate(text, voice, rate=f"{rate:+d}%", pitch=f"{pitch:+d}Hz")
|
228 |
await communicate.save(filename)
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
|
|
231 |
except edge_tts.exceptions.NoAudioReceived as e:
|
232 |
print(f"No audio received for text: '{text}' with voice: {voice}. Error: {e}")
|
233 |
return None, 0
|
@@ -239,6 +243,8 @@ def play_and_download_audio(file_path):
|
|
239 |
if file_path and os.path.exists(file_path):
|
240 |
st.audio(file_path)
|
241 |
st.markdown(get_download_link(file_path), unsafe_allow_html=True)
|
|
|
|
|
242 |
|
243 |
def load_mp3_viewer():
|
244 |
mp3_files = sorted(glob.glob("*.mp3"), key=os.path.getmtime)
|
@@ -264,6 +270,8 @@ async def save_chat_entry(username, message, voice, is_markdown=False):
|
|
264 |
if st.session_state.get('speech_processed', False) and st.session_state.get('message_input', '') == message:
|
265 |
st.session_state['message_input'] = ""
|
266 |
st.session_state['speech_processed'] = False
|
|
|
|
|
267 |
await broadcast_message(f"{username}|{message}", "chat")
|
268 |
st.session_state.last_chat_update = time.time()
|
269 |
st.session_state.chat_history.append(entry)
|
@@ -412,13 +420,15 @@ async def broadcast_message(message, room_id):
|
|
412 |
del st.session_state.active_connections[room_id][client_id]
|
413 |
|
414 |
async def run_websocket_server():
|
415 |
-
if not st.session_state.server_running:
|
416 |
server = await websockets.serve(websocket_handler, '0.0.0.0', 8765)
|
417 |
-
st.session_state
|
418 |
await server.wait_closed()
|
419 |
|
420 |
def start_websocket_server():
|
421 |
-
asyncio.
|
|
|
|
|
422 |
|
423 |
# 📚 PDF to Audio
|
424 |
class AudioProcessor:
|
@@ -605,7 +615,7 @@ def paste_image_component():
|
|
605 |
base64_str = paste_input.split(',')[1]
|
606 |
img_bytes = base64.b64decode(base64_str)
|
607 |
img = Image.open(io.BytesIO(img_bytes))
|
608 |
-
st.image(img, caption="Image Pasted Successfully", use_column_width=True)
|
609 |
return img
|
610 |
except Exception as e:
|
611 |
st.error(f"Error decoding pasted image: {e}")
|
@@ -617,7 +627,7 @@ def paste_image_component():
|
|
617 |
|
618 |
# 🎮 Main Interface
|
619 |
def main():
|
620 |
-
init_session_state()
|
621 |
load_mp3_viewer()
|
622 |
saved_username = load_username()
|
623 |
if saved_username and saved_username in FUN_USERNAMES:
|
@@ -670,7 +680,6 @@ def main():
|
|
670 |
with st.spinner("Saving image..."):
|
671 |
filename = asyncio.run(save_pasted_image(pasted_image, st.session_state.username, image_prompt))
|
672 |
if filename:
|
673 |
-
st.session_state.pasted_image_data = filename
|
674 |
st.success(f"Image saved as: {filename}")
|
675 |
if image_prompt:
|
676 |
with st.spinner("Processing with Claude..."):
|
@@ -781,7 +790,7 @@ def main():
|
|
781 |
|
782 |
st.subheader("🎵 Audio (MP3)")
|
783 |
for filename, (num, mp3) in sorted(st.session_state['mp3_files'].items(), key=lambda x: x[1][0]):
|
784 |
-
with st.expander(f"{num}. {
|
785 |
st.audio(mp3)
|
786 |
st.markdown(get_download_link(mp3, "mp3"), unsafe_allow_html=True)
|
787 |
|
@@ -902,7 +911,8 @@ def main():
|
|
902 |
else:
|
903 |
timer_placeholder.markdown(f"<p class='timer'>⏳ Next refresh in: {remaining_time} seconds</p>", unsafe_allow_html=True)
|
904 |
|
905 |
-
|
|
|
906 |
st.session_state.server_task = threading.Thread(target=start_websocket_server, daemon=True)
|
907 |
st.session_state.server_task.start()
|
908 |
|
|
|
226 |
try:
|
227 |
communicate = edge_tts.Communicate(text, voice, rate=f"{rate:+d}%", pitch=f"{pitch:+d}Hz")
|
228 |
await communicate.save(filename)
|
229 |
+
if os.path.exists(filename) and os.path.getsize(filename) > 0:
|
230 |
+
st.session_state['audio_cache'][cache_key] = filename
|
231 |
+
return filename, time.time() - start_time
|
232 |
+
else:
|
233 |
+
print(f"Audio file {filename} was not created or is empty.")
|
234 |
+
return None, 0
|
235 |
except edge_tts.exceptions.NoAudioReceived as e:
|
236 |
print(f"No audio received for text: '{text}' with voice: {voice}. Error: {e}")
|
237 |
return None, 0
|
|
|
243 |
if file_path and os.path.exists(file_path):
|
244 |
st.audio(file_path)
|
245 |
st.markdown(get_download_link(file_path), unsafe_allow_html=True)
|
246 |
+
else:
|
247 |
+
st.warning(f"Audio file not found: {file_path}")
|
248 |
|
249 |
def load_mp3_viewer():
|
250 |
mp3_files = sorted(glob.glob("*.mp3"), key=os.path.getmtime)
|
|
|
270 |
if st.session_state.get('speech_processed', False) and st.session_state.get('message_input', '') == message:
|
271 |
st.session_state['message_input'] = ""
|
272 |
st.session_state['speech_processed'] = False
|
273 |
+
else:
|
274 |
+
st.warning(f"Failed to generate audio for: {message}")
|
275 |
await broadcast_message(f"{username}|{message}", "chat")
|
276 |
st.session_state.last_chat_update = time.time()
|
277 |
st.session_state.chat_history.append(entry)
|
|
|
420 |
del st.session_state.active_connections[room_id][client_id]
|
421 |
|
422 |
async def run_websocket_server():
|
423 |
+
if not st.session_state.get('server_running', False): # Safe access with default
|
424 |
server = await websockets.serve(websocket_handler, '0.0.0.0', 8765)
|
425 |
+
st.session_state['server_running'] = True
|
426 |
await server.wait_closed()
|
427 |
|
428 |
def start_websocket_server():
|
429 |
+
loop = asyncio.new_event_loop()
|
430 |
+
asyncio.set_event_loop(loop)
|
431 |
+
loop.run_until_complete(run_websocket_server())
|
432 |
|
433 |
# 📚 PDF to Audio
|
434 |
class AudioProcessor:
|
|
|
615 |
base64_str = paste_input.split(',')[1]
|
616 |
img_bytes = base64.b64decode(base64_str)
|
617 |
img = Image.open(io.BytesIO(img_bytes))
|
618 |
+
st.image(img, caption="Image Pasted Successfully", use_column_width=True)
|
619 |
return img
|
620 |
except Exception as e:
|
621 |
st.error(f"Error decoding pasted image: {e}")
|
|
|
627 |
|
628 |
# 🎮 Main Interface
|
629 |
def main():
|
630 |
+
init_session_state() # Ensure session state is initialized before any threads
|
631 |
load_mp3_viewer()
|
632 |
saved_username = load_username()
|
633 |
if saved_username and saved_username in FUN_USERNAMES:
|
|
|
680 |
with st.spinner("Saving image..."):
|
681 |
filename = asyncio.run(save_pasted_image(pasted_image, st.session_state.username, image_prompt))
|
682 |
if filename:
|
|
|
683 |
st.success(f"Image saved as: {filename}")
|
684 |
if image_prompt:
|
685 |
with st.spinner("Processing with Claude..."):
|
|
|
790 |
|
791 |
st.subheader("🎵 Audio (MP3)")
|
792 |
for filename, (num, mp3) in sorted(st.session_state['mp3_files'].items(), key=lambda x: x[1][0]):
|
793 |
+
with st.expander(f"{num}. ${filename}"):
|
794 |
st.audio(mp3)
|
795 |
st.markdown(get_download_link(mp3, "mp3"), unsafe_allow_html=True)
|
796 |
|
|
|
911 |
else:
|
912 |
timer_placeholder.markdown(f"<p class='timer'>⏳ Next refresh in: {remaining_time} seconds</p>", unsafe_allow_html=True)
|
913 |
|
914 |
+
# Start WebSocket server only after session state is initialized
|
915 |
+
if not st.session_state.get('server_running', False) and not st.session_state.get('server_task', None):
|
916 |
st.session_state.server_task = threading.Thread(target=start_websocket_server, daemon=True)
|
917 |
st.session_state.server_task.start()
|
918 |
|