ManuelZafra commited on
Commit
1f71c1c
·
verified ·
1 Parent(s): 1f43783

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +503 -104
app.py CHANGED
@@ -6,17 +6,114 @@ import os
6
  import json
7
  import gradio as gr
8
  from tools.final_answer import FinalAnswerTool
 
 
 
 
 
 
9
 
10
  # File to save the history of recognized songs
11
  HISTORY_FILE = "song_history.json"
12
 
13
- # Supported languages (sin alemán)
14
  LANGUAGES = {
15
  "English": "en",
16
  "Español": "es",
17
  "Français": "fr"
18
  }
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  # Tool to recognize songs using AudD
21
  @tool
22
  def recognize_song(audio_path: str) -> dict:
@@ -142,19 +239,23 @@ def view_song_history(limit: int = 10) -> str:
142
  except Exception as e:
143
  return f"❌ Error getting history: {str(e)}"
144
 
145
- # Tool to get artist information in selected language (sin alemán)
146
  @tool
147
- def get_artist_info(artist_name: str, language: str = "en") -> str:
148
- """Gets background information and fun facts about a music artist in the specified language
 
149
  Args:
150
  artist_name: name of the artist to get information about
 
151
  language: language code (en, es, fr)
152
  """
153
- # Language-specific prompts (sin alemán)
154
  prompts = {
155
- "en": f"Provide interesting and fun facts about the music artist '{artist_name}' that fans would love to know. Include stories about their career, personal anecdotes, how their most famous songs were created, or surprising facts about their life. Focus on highlighting their contributions to music and anything that makes them unique as an artist. Keep it engaging and positive.",
156
- "es": f"Proporciona datos interesantes y curiosos sobre el artista musical '{artist_name}' que a los fans les encantaría conocer. Incluye historias sobre su carrera, anécdotas personales, cómo se crearon sus canciones más famosas o datos sorprendentes sobre su vida. Céntrate en destacar sus contribuciones a la música y cualquier cosa que les haga únicos como artistas. Mantenlo atractivo y positivo.",
157
- "fr": f"Fournissez des faits intéressants et amusants sur l'artiste musical '{artist_name}' que les fans aimeraient connaître. Incluez des histoires sur leur carrière, des anecdotes personnelles, comment leurs chansons les plus célèbres ont été créées, ou des faits surprenants sur leur vie. Concentrez-vous sur la mise en valeur de leurs contributions à la musique et tout ce qui les rend uniques en tant qu'artiste. Gardez-le engageant et positif."
 
 
158
  }
159
 
160
  # Default to English if language not supported
@@ -173,7 +274,7 @@ def get_artist_info(artist_name: str, language: str = "en") -> str:
173
  except Exception as e:
174
  return f"Could not retrieve information about {artist_name}: {str(e)}"
175
 
176
- # Chat with LLM tool (sin alemán)
177
  @tool
178
  def chat_with_assistant(query: str, artist_info: str = "", language: str = "en") -> str:
179
  """Chat with the AI assistant about any music related topic in the specified language
@@ -182,7 +283,7 @@ def chat_with_assistant(query: str, artist_info: str = "", language: str = "en")
182
  artist_info: previous artist info to provide context
183
  language: language code (en, es, fr)
184
  """
185
- # Language-specific system messages (sin alemán)
186
  system_messages = {
187
  "en": "You are a music expert assistant who specializes in providing engaging information about artists, songs, and music history. Focus on sharing interesting, fun facts that highlight the artist's unique contributions and stories.",
188
  "es": "Eres un asistente experto en música que se especializa en proporcionar información interesante sobre artistas, canciones e historia musical. Céntrate en compartir datos curiosos e interesantes que destaquen las contribuciones únicas y las historias del artista.",
@@ -242,171 +343,442 @@ agent = CodeAgent(
242
  prompt_templates=prompt_templates
243
  )
244
 
245
- # Gradio user interface
246
- with gr.Blocks(title="Music Recognition & Fun Facts") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  # State variables
248
  selected_language = gr.State("en")
 
249
  song_info_state = gr.State(None)
250
  artist_info_state = gr.State("")
251
- audio_status = gr.State("no_audio") # States: no_audio, loading, ready
 
 
 
 
 
 
 
 
252
 
253
  # Title and intro
254
- gr.Markdown("# 🎵 Music Recognition & Fun Facts")
255
- gr.Markdown("Identify songs, learn interesting facts about artists, and chat about music")
256
 
257
  # Language selection
258
  with gr.Row():
259
  language_dropdown = gr.Dropdown(
260
  choices=list(LANGUAGES.keys()),
261
  value="English",
262
- label="Choose your language"
263
  )
264
 
265
  # Combined recognition and chat interface
266
  with gr.Tab("Song Recognition & Chat"):
267
  # Audio status message
268
- audio_status_msg = gr.Markdown("*Por favor, graba o sube un clip de audio*")
 
 
 
269
 
270
  # Song recognition section
271
  with gr.Row():
272
  with gr.Column(scale=1):
273
- # Configuramos el componente de audio para usar el micrófono directamente
274
- audio_input = gr.Audio(source="microphone", type="filepath", visible=False)
275
- record_btn = gr.Button("🎙 REC MUSIC", size="lg", variant="primary")
276
- recognize_btn = gr.Button("🔍 RECOGNIZE SONG", variant="secondary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
- # Recognition results section (separate from chat)
279
  with gr.Row():
280
- recognition_results = gr.Markdown("")
281
 
282
  # Artist info section
283
  with gr.Row():
284
  artist_facts = gr.Markdown("")
285
 
 
 
 
 
286
  # Chat section
287
- gr.Markdown("### Pregúntame más sobre este artista o música en general")
288
- chat_history = gr.Chatbot(label="Music Chat")
 
 
289
 
290
  with gr.Row():
291
  chat_input = gr.Textbox(
292
- placeholder="Pregunta sobre el artista, la canción o cualquier tema musical...",
293
- label="Tu pregunta"
 
 
 
 
294
  )
295
- chat_btn = gr.Button("Enviar", variant="primary")
296
 
297
- # Function to handle audio recording
298
- def toggle_audio_widget():
299
- return gr.update(visible=True), "loading", "*Espera mientras se graba el audio... Haz clic en Stop cuando termines*"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
 
301
- # Function to update status when audio is recorded
302
- def update_audio_status(audio_path):
303
  if audio_path:
304
- return "ready", "✅ *¡Audio cargado! Listo para reconocer. Presiona RECOGNIZE SONG*"
 
 
 
 
 
 
 
 
 
305
  else:
306
- return "no_audio", "*Por favor, graba o sube un clip de audio*"
307
-
308
- # Recognition function (sin alemán)
309
- def process_audio(audio_path, language_name, status):
310
- if not audio_path or status != "ready":
311
- return None, "", "", "*Por favor, graba un clip de audio primero*"
312
-
313
- lang_code = LANGUAGES.get(language_name, "en")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
  try:
 
316
  result = recognize_song(audio_path)
317
 
318
  if "error" in result:
319
- return None, "", "", f"Error al reconocer la canción: {result['error']}"
320
 
321
- # Get artist information in selected language
322
- artist_info = get_artist_info(result['Artist'], lang_code)
 
323
 
324
- # Format recognition result based on language
325
- if lang_code == "en":
326
- recognition_msg = f"### 🎵 Recognized Song: {result['Song']}\n\n"
327
- recognition_msg += f"**🎤 Artist:** {result['Artist']}\n"
328
- recognition_msg += f"**📀 Album:** {result['Album']}\n\n"
329
- if result['Spotify'] != "Not available":
330
- recognition_msg += f"**🎧 [Listen on Spotify]({result['Spotify']})**\n"
331
- if result['Apple Music'] != "Not available":
332
- recognition_msg += f"**🍏 [Listen on Apple Music]({result['Apple Music']})**\n"
333
- elif lang_code == "es":
334
- recognition_msg = f"### 🎵 Canción Reconocida: {result['Song']}\n\n"
335
- recognition_msg += f"**🎤 Artista:** {result['Artist']}\n"
336
- recognition_msg += f"**📀 Álbum:** {result['Album']}\n\n"
337
- if result['Spotify'] != "Not available":
338
- recognition_msg += f"**🎧 [Escuchar en Spotify]({result['Spotify']})**\n"
339
- if result['Apple Music'] != "Not available":
340
- recognition_msg += f"**🍏 [Escuchar en Apple Music]({result['Apple Music']})**\n"
341
- elif lang_code == "fr":
342
- recognition_msg = f"### 🎵 Chanson Reconnue: {result['Song']}\n\n"
343
- recognition_msg += f"**🎤 Artiste:** {result['Artist']}\n"
344
- recognition_msg += f"**📀 Album:** {result['Album']}\n\n"
345
- if result['Spotify'] != "Not available":
346
- recognition_msg += f"**🎧 [Écouter sur Spotify]({result['Spotify']})**\n"
347
- if result['Apple Music'] != "Not available":
348
- recognition_msg += f"**🍏 [Écouter sur Apple Music]({result['Apple Music']})**\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
 
350
  # Artist info section title based on language
351
- if lang_code == "en":
352
- artist_facts_title = f"### 🌟 About {result['Artist']}\n\n"
353
- elif lang_code == "es":
354
- artist_facts_title = f"### 🌟 Sobre {result['Artist']}\n\n"
355
- elif lang_code == "fr":
356
- artist_facts_title = f"### 🌟 À propos de {result['Artist']}\n\n"
357
 
358
  # Format the artist info with a title
359
  artist_facts_content = artist_facts_title + artist_info
360
 
361
  # Update status message
362
- status_msg = "*¡Canción reconocida con éxito! Haz preguntas sobre el artista en el chat abajo*"
 
 
 
 
 
 
 
 
363
 
364
- return result, recognition_msg, artist_facts_content, status_msg
365
-
366
  except Exception as e:
367
- return None, "", "", f"❌ Error procesando el audio: {str(e)}"
 
368
 
369
  # Chat function
370
- def process_chat(query, language_name, song_info, artist_info):
371
  if not query:
372
  return []
373
 
374
- lang_code = LANGUAGES.get(language_name, "en")
375
-
376
  try:
377
  # Get response
378
  response = chat_with_assistant(query, artist_info, lang_code)
379
 
380
- return [(query, response)]
381
  except Exception as e:
382
- return [(query, f"Lo siento, no pude procesar tu solicitud: {str(e)}")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
 
384
- # Event handlers
385
- record_btn.click(
386
  fn=toggle_audio_widget,
 
 
 
 
 
 
 
 
 
 
 
387
  inputs=[],
388
- outputs=[audio_input, audio_status, audio_status_msg]
389
  )
390
 
 
391
  audio_input.change(
392
  fn=update_audio_status,
393
- inputs=[audio_input],
394
- outputs=[audio_status, audio_status_msg]
395
- )
396
-
397
- recognize_btn.click(
398
- fn=process_audio,
399
- inputs=[audio_input, language_dropdown, audio_status],
400
- outputs=[song_info_state, recognition_results, artist_facts, audio_status_msg]
 
 
 
 
 
 
 
 
 
 
401
  ).then(
402
- fn=lambda a: a,
403
- inputs=[artist_facts],
404
- outputs=[artist_info_state]
 
 
 
 
 
 
 
405
  )
406
 
 
407
  chat_btn.click(
408
  fn=process_chat,
409
- inputs=[chat_input, language_dropdown, song_info_state, artist_info_state],
410
  outputs=[chat_history]
411
  ).then(
412
  fn=lambda: "", # Clear input after sending
@@ -415,11 +787,11 @@ with gr.Blocks(title="Music Recognition & Fun Facts") as demo:
415
  )
416
 
417
  with gr.Tab("Song History"):
418
- gr.Markdown("### Historial de canciones reconocidas")
419
 
420
  with gr.Row():
421
- history_limit = gr.Slider(minimum=5, maximum=50, value=10, step=5, label="Número de canciones a mostrar")
422
- view_history_btn = gr.Button("📋 Ver Historial")
423
 
424
  history_output = gr.Markdown()
425
 
@@ -431,5 +803,32 @@ with gr.Blocks(title="Music Recognition & Fun Facts") as demo:
431
  inputs=[history_limit],
432
  outputs=[history_output]
433
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
- demo.launch()
 
 
 
 
 
 
 
 
 
6
  import json
7
  import gradio as gr
8
  from tools.final_answer import FinalAnswerTool
9
+ import logging
10
+
11
+ # Configurar logging para depuración
12
+ logging.basicConfig(level=logging.INFO,
13
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
14
+ logger = logging.getLogger('music_recognition_app')
15
 
16
  # File to save the history of recognized songs
17
  HISTORY_FILE = "song_history.json"
18
 
19
+ # Supported languages - removed German
20
  LANGUAGES = {
21
  "English": "en",
22
  "Español": "es",
23
  "Français": "fr"
24
  }
25
 
26
+ # UI messages for different languages
27
+ UI_MESSAGES = {
28
+ "en": {
29
+ "title": "Music Recognition & Fun Facts",
30
+ "subtitle": "Record a song and get interesting facts about the artist",
31
+ "choose_language": "Choose your language",
32
+ "rec_button": "🎙 REC AND IDENTIFY SONG",
33
+ "please_record": "Please click REC to record a song or upload an audio file",
34
+ "recording": "Recording... Click Stop when done",
35
+ "audio_loaded": "✅ Audio loaded! Identifying song...",
36
+ "loading_audio": "Please wait while processing the audio",
37
+ "searching_song": "Searching for your song in the sound multiverse, please wait...",
38
+ "identified_song": "🎵 Identified Song: \"{song}\" by {artist}",
39
+ "loading_artist_info": "Now loading interesting facts about {artist}...",
40
+ "song_recognized": "Song successfully recognized! Ask questions about the artist in the chat below",
41
+ "about_artist": "About",
42
+ "ask_more": "Ask me more about this artist or music in general",
43
+ "chat_placeholder": "Ask about the artist, song, or anything music related...",
44
+ "send_button": "Send",
45
+ "history_tab": "Song History",
46
+ "history_title": "History of recognized songs",
47
+ "songs_to_show": "Number of songs to show",
48
+ "view_history": "📋 View History",
49
+ "recognized_song": "Recognized Song",
50
+ "artist": "Artist",
51
+ "album": "Album",
52
+ "listen_spotify": "Listen on Spotify",
53
+ "listen_apple": "Listen on Apple Music",
54
+ "no_audio_error": "Please record an audio clip first",
55
+ "processing_error": "Error processing audio"
56
+ },
57
+ "es": {
58
+ "title": "Reconocimiento de Música y Datos Curiosos",
59
+ "subtitle": "Graba una canción y obtén datos interesantes sobre el artista",
60
+ "choose_language": "Elige tu idioma",
61
+ "rec_button": "🎙 GRABAR E IDENTIFICAR CANCIÓN",
62
+ "please_record": "Haz clic en GRABAR para grabar una canción o sube un archivo de audio",
63
+ "recording": "Grabando... Haz clic en Detener cuando termines",
64
+ "audio_loaded": "✅ ¡Audio cargado! Identificando canción...",
65
+ "loading_audio": "Por favor espere mientras se procesa el audio",
66
+ "searching_song": "Buscando tu canción en el multiverso sonoro, por favor espera...",
67
+ "identified_song": "🎵 Canción identificada: \"{song}\" por {artist}",
68
+ "loading_artist_info": "Ahora cargando datos interesantes sobre {artist}...",
69
+ "song_recognized": "¡Canción reconocida con éxito! Haz preguntas sobre el artista en el chat de abajo",
70
+ "about_artist": "Sobre",
71
+ "ask_more": "Pregúntame más sobre este artista o música en general",
72
+ "chat_placeholder": "Pregunta sobre el artista, canción o cualquier tema relacionado con la música...",
73
+ "send_button": "Enviar",
74
+ "history_tab": "Historial de Canciones",
75
+ "history_title": "Historial de canciones reconocidas",
76
+ "songs_to_show": "Número de canciones para mostrar",
77
+ "view_history": "📋 Ver Historial",
78
+ "recognized_song": "Canción Reconocida",
79
+ "artist": "Artista",
80
+ "album": "Álbum",
81
+ "listen_spotify": "Escuchar en Spotify",
82
+ "listen_apple": "Escuchar en Apple Music",
83
+ "no_audio_error": "Por favor graba un clip de audio primero",
84
+ "processing_error": "Error al procesar el audio"
85
+ },
86
+ "fr": {
87
+ "title": "Reconnaissance de Musique et Anecdotes",
88
+ "subtitle": "Enregistrez une chanson et découvrez des faits intéressants sur l'artiste",
89
+ "choose_language": "Choisissez votre langue",
90
+ "rec_button": "🎙 ENREGISTRER ET IDENTIFIER LA CHANSON",
91
+ "please_record": "Cliquez sur ENREGISTRER pour enregistrer une chanson ou téléchargez un fichier audio",
92
+ "recording": "Enregistrement... Cliquez sur Arrêter quand vous avez terminé",
93
+ "audio_loaded": "✅ Audio chargé ! Identification de la chanson...",
94
+ "loading_audio": "Veuillez patienter pendant le traitement de l'audio",
95
+ "searching_song": "Recherche de votre chanson dans le multivers sonore, veuillez patienter...",
96
+ "identified_song": "🎵 Chanson identifiée: \"{song}\" par {artist}",
97
+ "loading_artist_info": "Chargement de faits intéressants sur {artist}...",
98
+ "song_recognized": "Chanson reconnue avec succès ! Posez des questions sur l'artiste dans le chat ci-dessous",
99
+ "about_artist": "À propos de",
100
+ "ask_more": "Demandez-moi plus d'informations sur cet artiste ou sur la musique en général",
101
+ "chat_placeholder": "Posez une question sur l'artiste, la chanson ou tout ce qui concerne la musique...",
102
+ "send_button": "Envoyer",
103
+ "history_tab": "Historique des Chansons",
104
+ "history_title": "Historique des chansons reconnues",
105
+ "songs_to_show": "Nombre de chansons à afficher",
106
+ "view_history": "📋 Voir l'historique",
107
+ "recognized_song": "Chanson Reconnue",
108
+ "artist": "Artiste",
109
+ "album": "Album",
110
+ "listen_spotify": "Écouter sur Spotify",
111
+ "listen_apple": "Écouter sur Apple Music",
112
+ "no_audio_error": "Veuillez d'abord enregistrer un clip audio",
113
+ "processing_error": "Erreur lors du traitement de l'audio"
114
+ }
115
+ }
116
+
117
  # Tool to recognize songs using AudD
118
  @tool
119
  def recognize_song(audio_path: str) -> dict:
 
239
  except Exception as e:
240
  return f"❌ Error getting history: {str(e)}"
241
 
242
+ # Tool to get artist information in selected language with enhanced details
243
  @tool
244
+ def get_artist_info(artist_name: str, song_name: str = "", language: str = "en") -> str:
245
+ """Gets detailed background information, fun facts about a music artist and the specific song in the specified language
246
+
247
  Args:
248
  artist_name: name of the artist to get information about
249
+ song_name: name of the song (if available)
250
  language: language code (en, es, fr)
251
  """
252
+ # Language-specific prompts
253
  prompts = {
254
+ "en": f"Provide a comprehensive overview about the music artist '{artist_name}'. Include the following sections clearly marked with headers:\n\n1. General Biography: Brief overview of their career and significance in music.\n\n2. Fun Facts: 4-5 surprising or interesting facts about the artist or group that fans would find fascinating.\n\n3. Behind-the-scenes Anecdotes: 2-3 memorable stories about the artist's career, performances, or personal life that showcase their character or impact.\n\n" + (f'4. About the Song "{song_name}": If you know anything specific about how this song was created, its meaning, its impact, or interesting trivia related to it, please share those details.' if song_name else '') + "\n\nKeep the tone engaging and enthusiastic, highlighting what makes this artist unique and beloved by fans. Limit your response to around 500 words total.",
255
+
256
+ "es": f"Proporciona una visión completa sobre el artista musical '{artist_name}'. Incluye las siguientes secciones claramente marcadas con encabezados:\n\n1. Biografía General: Breve resumen de su carrera y significado en la música.\n\n2. Datos Curiosos: 4-5 hechos sorprendentes o interesantes sobre el artista o grupo que los fans encontrarían fascinantes.\n\n3. Anécdotas entre bastidores: 2-3 historias memorables sobre la carrera del artista, actuaciones o vida personal que muestren su carácter o impacto.\n\n" + (f'4. Sobre la canción "{song_name}": Si conoces algo específico sobre cómo se creó esta canción, su significado, su impacto o curiosidades interesantes relacionadas con ella, por favor comparte esos detalles.' if song_name else '') + "\n\nMantén un tono atractivo y entusiasta, destacando lo que hace que este artista sea único y querido por los fans. Limita tu respuesta a alrededor de 500 palabras en total.",
257
+
258
+ "fr": f"Fournissez un aperçu complet de l'artiste musical '{artist_name}'. Incluez les sections suivantes clairement marquées avec des en-têtes:\n\n1. Biographie générale: Bref aperçu de sa carrière et de son importance dans la musique.\n\n2. Anecdotes intéressantes: 4-5 faits surprenants ou intéressants sur l'artiste ou le groupe que les fans trouveraient fascinants.\n\n3. Anecdotes en coulisses: 2-3 histoires mémorables sur la carrière de l'artiste, ses performances ou sa vie personnelle qui mettent en valeur son caractère ou son impact.\n\n" + (f'4. À propos de la chanson "{song_name}": Si vous connaissez quelque chose de spécifique sur la façon dont cette chanson a été créée, sa signification, son impact ou des anecdotes intéressantes liées à elle, veuillez partager ces détails.' if song_name else '') + "\n\nGardez un ton engageant et enthousiaste, mettant en évidence ce qui rend cet artiste unique et apprécié des fans. Limitez votre réponse à environ 500 mots au total."
259
  }
260
 
261
  # Default to English if language not supported
 
274
  except Exception as e:
275
  return f"Could not retrieve information about {artist_name}: {str(e)}"
276
 
277
+ # Chat with LLM tool
278
  @tool
279
  def chat_with_assistant(query: str, artist_info: str = "", language: str = "en") -> str:
280
  """Chat with the AI assistant about any music related topic in the specified language
 
283
  artist_info: previous artist info to provide context
284
  language: language code (en, es, fr)
285
  """
286
+ # Language-specific system messages
287
  system_messages = {
288
  "en": "You are a music expert assistant who specializes in providing engaging information about artists, songs, and music history. Focus on sharing interesting, fun facts that highlight the artist's unique contributions and stories.",
289
  "es": "Eres un asistente experto en música que se especializa en proporcionar información interesante sobre artistas, canciones e historia musical. Céntrate en compartir datos curiosos e interesantes que destaquen las contribuciones únicas y las historias del artista.",
 
343
  prompt_templates=prompt_templates
344
  )
345
 
346
+ # Gradio user interface con CSS personalizado para mejor experiencia móvil
347
+ with gr.Blocks(title="Music Recognition & Fun Facts", css="""
348
+ .large-button {
349
+ min-height: 60px !important;
350
+ font-size: 18px !important;
351
+ padding: 15px !important;
352
+ }
353
+ @media (max-width: 600px) {
354
+ .large-button {
355
+ width: 100% !important;
356
+ margin-bottom: 10px !important;
357
+ }
358
+ #audio-input {
359
+ width: 100% !important;
360
+ margin-top: 10px !important;
361
+ margin-bottom: 10px !important;
362
+ }
363
+ /* Hacer el botón de grabar y parar más grande */
364
+ button.record, button.stop {
365
+ width: 60px !important;
366
+ height: 60px !important;
367
+ border-radius: 50% !important;
368
+ }
369
+ /* Hacer el texto de error más visible */
370
+ .error-text {
371
+ color: red !important;
372
+ font-weight: bold !important;
373
+ font-size: 16px !important;
374
+ }
375
+ /* Destacar el título de la canción identificada */
376
+ .identified-song {
377
+ font-size: 1.3em !important;
378
+ margin: 15px 0 !important;
379
+ padding: 10px !important;
380
+ border-radius: 5px !important;
381
+ background-color: rgba(0, 123, 255, 0.1) !important;
382
+ border-left: 4px solid #007bff !important;
383
+ }
384
+ }
385
+ /* Estilos para el indicador de micrófono */
386
+ #mic-status {
387
+ margin-top: 5px;
388
+ margin-bottom: 15px;
389
+ font-style: italic;
390
+ }
391
+ /* Destacar el título de la canción identificada */
392
+ .identified-song {
393
+ font-size: 1.2em;
394
+ margin: 10px 0;
395
+ padding: 8px;
396
+ border-radius: 5px;
397
+ background-color: rgba(0, 123, 255, 0.1);
398
+ border-left: 4px solid #007bff;
399
+ }
400
+ """) as demo:
401
  # State variables
402
  selected_language = gr.State("en")
403
+ lang_code = gr.State("en")
404
  song_info_state = gr.State(None)
405
  artist_info_state = gr.State("")
406
+ song_name_state = gr.State("")
407
+ audio_status = gr.State("no_audio") # States: no_audio, loading, ready, processing
408
+
409
+ # Function to get UI messages based on language
410
+ def get_ui_message(message_key, language_code="en"):
411
+ return UI_MESSAGES.get(language_code, UI_MESSAGES["en"]).get(message_key, UI_MESSAGES["en"][message_key])
412
+
413
+ # Initial UI language is English
414
+ current_lang = "en"
415
 
416
  # Title and intro
417
+ title_component = gr.Markdown(f"# 🎵 {get_ui_message('title', current_lang)}")
418
+ subtitle_component = gr.Markdown(get_ui_message('subtitle', current_lang))
419
 
420
  # Language selection
421
  with gr.Row():
422
  language_dropdown = gr.Dropdown(
423
  choices=list(LANGUAGES.keys()),
424
  value="English",
425
+ label=get_ui_message('choose_language', current_lang)
426
  )
427
 
428
  # Combined recognition and chat interface
429
  with gr.Tab("Song Recognition & Chat"):
430
  # Audio status message
431
+ audio_status_msg = gr.Markdown(f"*{get_ui_message('please_record', current_lang)}*")
432
+
433
+ # Componente para mostrar inmediatamente la canción identificada
434
+ song_identification = gr.Markdown("", elem_classes="identified-song")
435
 
436
  # Song recognition section
437
  with gr.Row():
438
  with gr.Column(scale=1):
439
+ # Audio input siempre visible
440
+ audio_input = gr.Audio(
441
+ label="Audio Recording",
442
+ type="filepath",
443
+ visible=True,
444
+ sources=["microphone", "upload"],
445
+ streaming=False,
446
+ elem_id="audio-input",
447
+ format="mp3",
448
+ autoplay=False,
449
+ show_download_button=False,
450
+ interactive=True
451
+ )
452
+
453
+ # Solo un botón que abre el audio y después identifica
454
+ rec_btn = gr.Button(
455
+ get_ui_message('rec_button', current_lang),
456
+ size="lg",
457
+ variant="primary",
458
+ scale=2,
459
+ elem_id="record-button",
460
+ elem_classes="large-button"
461
+ )
462
+
463
+ # Indicador de estado del micrófono/proceso
464
+ microphone_status = gr.Markdown("", elem_id="mic-status")
465
 
466
+ # Processing indicator
467
  with gr.Row():
468
+ processing_indicator = gr.Markdown("")
469
 
470
  # Artist info section
471
  with gr.Row():
472
  artist_facts = gr.Markdown("")
473
 
474
+ # Recognition results section with links
475
+ with gr.Row():
476
+ recognition_results = gr.Markdown("")
477
+
478
  # Chat section
479
+ with gr.Row():
480
+ chat_section_title = gr.Markdown(f"### {get_ui_message('ask_more', current_lang)}")
481
+
482
+ chat_history = gr.Chatbot(label="Music Chat", type="messages")
483
 
484
  with gr.Row():
485
  chat_input = gr.Textbox(
486
+ placeholder=get_ui_message('chat_placeholder', current_lang),
487
+ label="Your question"
488
+ )
489
+ chat_btn = gr.Button(
490
+ get_ui_message('send_button', current_lang),
491
+ variant="primary"
492
  )
 
493
 
494
+ # Function to handle language changes
495
+ def update_ui_language(language_name):
496
+ lang_code = LANGUAGES.get(language_name, "en")
497
+
498
+ return (
499
+ f"# 🎵 {get_ui_message('title', lang_code)}",
500
+ get_ui_message('subtitle', lang_code),
501
+ gr.update(label=get_ui_message('choose_language', lang_code)),
502
+ gr.update(value=get_ui_message('rec_button', lang_code)),
503
+ f"*{get_ui_message('please_record', lang_code)}*",
504
+ gr.update(value=get_ui_message('send_button', lang_code)),
505
+ f"### {get_ui_message('ask_more', lang_code)}",
506
+ gr.update(placeholder=get_ui_message('chat_placeholder', lang_code)),
507
+ lang_code
508
+ )
509
+
510
+ # Function to handle audio recording with automatic recognition
511
+ def toggle_audio_widget(lang_code):
512
+ # Mensaje detallado con instrucciones para solucionar problemas de micrófono
513
+ mobile_guidance = ""
514
+
515
+ if lang_code == "en":
516
+ mobile_guidance = """
517
+ *Recording... Click Stop when done. The song will be identified automatically.*
518
+
519
+ **If you're having trouble with the microphone:**
520
+ - Make sure your browser has permission to access your microphone
521
+ - Make sure you're using a secure connection (HTTPS)
522
+ - Your microphone might be in use by another application
523
+ - Try refreshing the page and allow microphone access when prompted
524
+ - If using a mobile device, try using Chrome or Safari
525
+ """
526
+ elif lang_code == "es":
527
+ mobile_guidance = """
528
+ *Grabando... Haz clic en Detener cuando termines. La canción se identificará automáticamente.*
529
+
530
+ **Si tienes problemas con el micrófono:**
531
+ - Asegúrate de que tu navegador tiene permiso para acceder a tu micrófono
532
+ - Asegúrate de que estás usando una conexión segura (HTTPS)
533
+ - Tu micrófono podría estar siendo usado por otra aplicación
534
+ - Intenta refrescar la página y permitir el acceso al micrófono cuando se te solicite
535
+ - Si usas un dispositivo móvil, intenta usar Chrome o Safari
536
+ """
537
+ else: # French
538
+ mobile_guidance = """
539
+ *Enregistrement... Cliquez sur Arrêter quand vous avez terminé. La chanson sera identifiée automatiquement.*
540
+
541
+ **Si vous avez des problèmes avec le microphone:**
542
+ - Assurez-vous que votre navigateur a l'autorisation d'accéder à votre microphone
543
+ - Assurez-vous que vous utilisez une connexion sécurisée (HTTPS)
544
+ - Votre microphone pourrait être utilisé par une autre application
545
+ - Essayez d'actualiser la page et d'autoriser l'accès au microphone lorsque vous y êtes invité
546
+ - Si vous utilisez un appareil mobile, essayez d'utiliser Chrome ou Safari
547
+ """
548
+
549
+ # Hacer visible el componente de audio
550
+ return (
551
+ gr.update(visible=True),
552
+ "loading",
553
+ mobile_guidance,
554
+ "", # Clear processing indicator
555
+ "" # Clear song identification
556
+ )
557
 
558
+ # Function to update status when audio is uploaded/recorded and trigger automatic recognition
559
+ def update_audio_status(audio_path, lang_code):
560
  if audio_path:
561
+ audio_loaded_msg = f"*{get_ui_message('audio_loaded', lang_code)}*"
562
+ # Activar automáticamente el reconocimiento
563
+ return (
564
+ "ready",
565
+ audio_loaded_msg,
566
+ f"*{get_ui_message('searching_song', lang_code)}*",
567
+ "",
568
+ audio_path,
569
+ lang_code
570
+ )
571
  else:
572
+ # Si no hay audio, probable problema con el micrófono
573
+ troubleshooting = ""
574
+
575
+ if lang_code == "en":
576
+ troubleshooting = """
577
+ *No audio was recorded. Please try again.*
578
+
579
+ **Microphone troubleshooting:**
580
+ - Check if your browser shows a microphone permission dialog
581
+ - Make sure microphone permissions are granted in your browser settings
582
+ - Try using a different browser (Chrome or Safari recommended)
583
+ - Check if your microphone is working in other applications
584
+ """
585
+ elif lang_code == "es":
586
+ troubleshooting = """
587
+ *No se grabó audio. Por favor, inténtalo de nuevo.*
588
+
589
+ **Solución de problemas de micrófono:**
590
+ - Verifica si tu navegador muestra un diálogo de permiso de micrófono
591
+ - Asegúrate de que los permisos de micrófono estén concedidos en la configuración de tu navegador
592
+ - Intenta usar un navegador diferente (se recomienda Chrome o Safari)
593
+ - Comprueba si tu micrófono funciona en otras aplicaciones
594
+ """
595
+ else: # French
596
+ troubleshooting = """
597
+ *Aucun audio n'a été enregistré. Veuillez réessayer.*
598
+
599
+ **Dépannage du microphone:**
600
+ - Vérifiez si votre navigateur affiche une boîte de dialogue d'autorisation de microphone
601
+ - Assurez-vous que les autorisations de microphone sont accordées dans les paramètres de votre navigateur
602
+ - Essayez d'utiliser un navigateur différent (Chrome ou Safari recommandé)
603
+ - Vérifiez si votre microphone fonctionne dans d'autres applications
604
+ """
605
+
606
+ return (
607
+ "no_audio",
608
+ troubleshooting,
609
+ "", # Clear processing indicator
610
+ "", # Clear song identification
611
+ None, # No audio path
612
+ lang_code
613
+ )
614
+
615
+ # Initial song recognition (just identifies the song)
616
+ def initial_song_recognition(audio_path, lang_code):
617
+ if not audio_path:
618
+ return "", ""
619
 
620
  try:
621
+ # Reconocer la canción
622
  result = recognize_song(audio_path)
623
 
624
  if "error" in result:
625
+ return f"Error recognizing the song: {result['error']}", ""
626
 
627
+ # Obtener datos básicos
628
+ song_name = result['Song']
629
+ artist_name = result['Artist']
630
 
631
+ # Mensaje de identificación rápida
632
+ identified_song_msg = get_ui_message('identified_song', lang_code).format(
633
+ song=song_name,
634
+ artist=artist_name
635
+ )
636
+
637
+ # Mensaje de carga de info del artista
638
+ loading_artist_info_msg = get_ui_message('loading_artist_info', lang_code).format(
639
+ artist=artist_name
640
+ )
641
+
642
+ # Devolver solo el mensaje de identificación y el resultado
643
+ return identified_song_msg, json.dumps(result)
644
+
645
+ except Exception as e:
646
+ error_msg = f"❌ {get_ui_message('processing_error', lang_code)}: {str(e)}"
647
+ return error_msg, ""
648
+
649
+ # Load detailed artist information
650
+ def load_artist_info(song_result_json, lang_code):
651
+ if not song_result_json:
652
+ return "", "", "", "", ""
653
+
654
+ try:
655
+ # Convertir el JSON a dict
656
+ result = json.loads(song_result_json)
657
+
658
+ # Obtener datos básicos
659
+ song_name = result['Song']
660
+ artist_name = result['Artist']
661
+
662
+ # Obtener información detallada del artista
663
+ artist_info = get_artist_info(artist_name, song_name, lang_code)
664
+
665
+ # Format recognition result based on language (links y detalles)
666
+ recognition_msg = f"### 🎵 {get_ui_message('recognized_song', lang_code)}: {result['Song']}\n\n"
667
+ recognition_msg += f"**🎤 {get_ui_message('artist', lang_code)}:** {result['Artist']}\n"
668
+ recognition_msg += f"**📀 {get_ui_message('album', lang_code)}:** {result['Album']}\n\n"
669
+
670
+ if result['Spotify'] != "Not available":
671
+ recognition_msg += f"**🎧 [{get_ui_message('listen_spotify', lang_code)}]({result['Spotify']})**\n"
672
+ if result['Apple Music'] != "Not available":
673
+ recognition_msg += f"**🍏 [{get_ui_message('listen_apple', lang_code)}]({result['Apple Music']})**\n"
674
 
675
  # Artist info section title based on language
676
+ artist_facts_title = f"### 🌟 {get_ui_message('about_artist', lang_code)} {result['Artist']}\n\n"
 
 
 
 
 
677
 
678
  # Format the artist info with a title
679
  artist_facts_content = artist_facts_title + artist_info
680
 
681
  # Update status message
682
+ status_msg = f"*{get_ui_message('song_recognized', lang_code)}*"
683
+
684
+ return (
685
+ recognition_msg, # Recognition result with links
686
+ artist_facts_content, # Artist info
687
+ status_msg, # Status message
688
+ song_name, # Song name for state
689
+ artist_name # Artist name for state
690
+ )
691
 
 
 
692
  except Exception as e:
693
+ error_msg = f"❌ Error loading artist information: {str(e)}"
694
+ return error_msg, "", "", "", ""
695
 
696
  # Chat function
697
+ def process_chat(query, language_name, song_info, artist_info, lang_code):
698
  if not query:
699
  return []
700
 
 
 
701
  try:
702
  # Get response
703
  response = chat_with_assistant(query, artist_info, lang_code)
704
 
705
+ return [{"role": "user", "content": query}, {"role": "assistant", "content": response}]
706
  except Exception as e:
707
+ return [{"role": "user", "content": query}, {"role": "assistant", "content": f"Sorry, I couldn't process your request: {str(e)}"}]
708
+
709
+ # Language selection event handler
710
+ language_dropdown.change(
711
+ fn=update_ui_language,
712
+ inputs=[language_dropdown],
713
+ outputs=[
714
+ title_component,
715
+ subtitle_component,
716
+ language_dropdown,
717
+ rec_btn,
718
+ audio_status_msg,
719
+ chat_btn,
720
+ chat_section_title,
721
+ chat_input,
722
+ lang_code
723
+ ]
724
+ )
725
 
726
+ # Event handlers - Mostrar componente de audio al hacer clic en REC
727
+ rec_btn.click(
728
  fn=toggle_audio_widget,
729
+ inputs=[lang_code],
730
+ outputs=[
731
+ audio_input,
732
+ audio_status,
733
+ audio_status_msg,
734
+ processing_indicator,
735
+ song_identification
736
+ ]
737
+ ).then(
738
+ # Actualizar el estado del micrófono
739
+ fn=lambda: "Microphone activated. The song will be identified automatically when you stop recording.",
740
  inputs=[],
741
+ outputs=[microphone_status]
742
  )
743
 
744
+ # Reconocer automáticamente cuando se sube o graba audio
745
  audio_input.change(
746
  fn=update_audio_status,
747
+ inputs=[audio_input, lang_code],
748
+ outputs=[
749
+ audio_status,
750
+ audio_status_msg,
751
+ processing_indicator,
752
+ song_identification,
753
+ # Pasamos estos dos para activar el reconocimiento automático
754
+ audio_input, # Audio path
755
+ lang_code # Language code
756
+ ]
757
+ ).then(
758
+ # Etapa 1: Identificación rápida de la canción
759
+ fn=initial_song_recognition,
760
+ inputs=[audio_input, lang_code],
761
+ outputs=[
762
+ song_identification, # Mostrar inmediatamente el título identificado
763
+ song_info_state # Guardar resultado para siguiente etapa
764
+ ]
765
  ).then(
766
+ # Etapa 2: Cargar información detallada del artista
767
+ fn=load_artist_info,
768
+ inputs=[song_info_state, lang_code],
769
+ outputs=[
770
+ recognition_results, # Resultado con links
771
+ artist_facts, # Información del artista
772
+ audio_status_msg, # Mensaje de estado
773
+ song_name_state, # Guardar nombre de canción
774
+ artist_info_state # Guardar nombre de artista
775
+ ]
776
  )
777
 
778
+ # Botón de chat
779
  chat_btn.click(
780
  fn=process_chat,
781
+ inputs=[chat_input, language_dropdown, song_info_state, artist_info_state, lang_code],
782
  outputs=[chat_history]
783
  ).then(
784
  fn=lambda: "", # Clear input after sending
 
787
  )
788
 
789
  with gr.Tab("Song History"):
790
+ history_tab_title = gr.Markdown(f"### {get_ui_message('history_title', current_lang)}")
791
 
792
  with gr.Row():
793
+ history_limit = gr.Slider(minimum=5, maximum=50, value=10, step=5, label=get_ui_message('songs_to_show', current_lang))
794
+ view_history_btn = gr.Button(get_ui_message('view_history', current_lang))
795
 
796
  history_output = gr.Markdown()
797
 
 
803
  inputs=[history_limit],
804
  outputs=[history_output]
805
  )
806
+
807
+ # Update history tab language
808
+ def update_history_tab_language(lang_name):
809
+ lang_code = LANGUAGES.get(lang_name, 'en')
810
+ return (
811
+ f"### {get_ui_message('history_title', lang_code)}",
812
+ gr.update(label=get_ui_message('songs_to_show', lang_code)),
813
+ gr.update(value=get_ui_message('view_history', lang_code))
814
+ )
815
+
816
+ language_dropdown.change(
817
+ fn=update_history_tab_language,
818
+ inputs=[language_dropdown],
819
+ outputs=[
820
+ history_tab_title,
821
+ history_limit,
822
+ view_history_btn
823
+ ]
824
+ )
825
 
826
+ # Set the configuration for mobile compatibility
827
+ demo.launch(
828
+ show_error=True,
829
+ share=True,
830
+ inbrowser=True,
831
+ debug=True,
832
+ allowed_paths=[],
833
+ server_name="0.0.0.0" # Esto permite conexiones desde cualquier dirección
834
+ )