Spaces:
Paused
Paused
| import gradio as gr | |
| # ────────────────────────────────────────────── | |
| # CAPÍTULOS DEL GÉNESIS | |
| # ────────────────────────────────────────────── | |
| CAPITULOS = [ | |
| {"titulo": "Génesis · Capítulo 1", "archivo": "audio/genesis_01.mp3"}, | |
| {"titulo": "Génesis · Capítulo 2", "archivo": "audio/genesis_02.mp3"}, | |
| {"titulo": "Génesis · Capítulo 3", "archivo": "audio/genesis_03.mp3"}, | |
| {"titulo": "Génesis · Capítulo 4", "archivo": "audio/genesis_04.mp3"}, | |
| {"titulo": "Génesis · Capítulo 5", "archivo": "audio/genesis_05.mp3"}, | |
| {"titulo": "Génesis · Capítulo 6", "archivo": "audio/genesis_06.mp3"}, | |
| {"titulo": "Génesis · Capítulo 7", "archivo": "audio/genesis_07.mp3"}, | |
| {"titulo": "Génesis · Capítulo 8", "archivo": "audio/genesis_08.mp3"}, | |
| {"titulo": "Génesis · Capítulo 9", "archivo": "audio/genesis_09.mp3"}, | |
| {"titulo": "Génesis · Capítulo 10", "archivo": "audio/genesis_10.mp3"}, | |
| ] | |
| TOTAL = len(CAPITULOS) | |
| def cargar_capitulo(indice, autoplay=False): | |
| """Devuelve el update del reproductor + el texto del capítulo actual.""" | |
| indice = max(0, min(indice, TOTAL - 1)) | |
| cap = CAPITULOS[indice] | |
| texto = f"📖 Reproduciendo ahora: **{cap['titulo']}** ({indice + 1} de {TOTAL})" | |
| return ( | |
| gr.update(value=cap["archivo"], autoplay=autoplay), | |
| texto, | |
| indice, | |
| ) | |
| def iniciar_desde_boton(indice_boton): | |
| audio, texto, idx = cargar_capitulo(indice_boton, autoplay=True) | |
| return audio, texto, idx | |
| def iniciar_todo(): | |
| return iniciar_desde_boton(0) | |
| def al_terminar_capitulo(indice_actual): | |
| siguiente = indice_actual + 1 | |
| if siguiente >= TOTAL: | |
| return ( | |
| gr.update(value=CAPITULOS[indice_actual]["archivo"], autoplay=False), | |
| f"✨ Has completado el Libro del Génesis, capítulos 1 al {TOTAL}. La lectura ha concluido en paz. ✨", | |
| indice_actual, | |
| ) | |
| return cargar_capitulo(siguiente, autoplay=True) | |
| # ────────────────────────────────────────────── | |
| # ESTILO CELESTIAL Y DIVINO | |
| # ────────────────────────────────────────────── | |
| CSS = """ | |
| @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700&family=EB+Garamond:ital@0;1&display=swap'); | |
| .gradio-container { | |
| background: radial-gradient(ellipse at top, #0b1030 0%, #05061a 55%, #000000 100%) !important; | |
| background-attachment: fixed !important; | |
| position: relative; | |
| overflow-x: hidden; | |
| } | |
| .gradio-container::before { | |
| content: ""; | |
| position: fixed; | |
| inset: 0; | |
| pointer-events: none; | |
| background-image: | |
| radial-gradient(1.5px 1.5px at 20% 30%, #ffffff 100%, transparent 0), | |
| radial-gradient(1.5px 1.5px at 65% 15%, #ffe9b8 100%, transparent 0), | |
| radial-gradient(2px 2px at 80% 55%, #ffffff 100%, transparent 0), | |
| radial-gradient(1px 1px at 40% 80%, #ffffff 100%, transparent 0), | |
| radial-gradient(1.5px 1.5px at 90% 80%, #ffe9b8 100%, transparent 0), | |
| radial-gradient(1px 1px at 10% 65%, #ffffff 100%, transparent 0), | |
| radial-gradient(2px 2px at 55% 45%, #ffffff 100%, transparent 0), | |
| radial-gradient(1.5px 1.5px at 30% 10%, #ffffff 100%, transparent 0); | |
| background-repeat: repeat; | |
| background-size: 700px 700px; | |
| animation: centellear 6s ease-in-out infinite alternate; | |
| opacity: 0.6; | |
| z-index: 0; | |
| } | |
| @keyframes centellear { | |
| from { opacity: 0.35; } | |
| to { opacity: 0.85; } | |
| } | |
| #titulo-divino { | |
| text-align: center; | |
| font-family: 'Cinzel', serif; | |
| color: #f4dfa3; | |
| text-shadow: 0 0 18px rgba(244, 223, 163, 0.55), 0 0 40px rgba(120, 90, 200, 0.35); | |
| font-size: 2.4em; | |
| letter-spacing: 3px; | |
| margin-bottom: 0; | |
| } | |
| #subtitulo-divino { | |
| text-align: center; | |
| font-family: 'EB Garamond', serif; | |
| font-style: italic; | |
| color: #c9c3e8; | |
| font-size: 1.15em; | |
| margin-top: 4px; | |
| margin-bottom: 25px; | |
| } | |
| .panel-celestial { | |
| background: linear-gradient(160deg, rgba(20, 20, 55, 0.75), rgba(8, 8, 25, 0.85)) !important; | |
| border: 1px solid rgba(244, 223, 163, 0.35) !important; | |
| border-radius: 18px !important; | |
| box-shadow: 0 0 35px rgba(120, 90, 200, 0.25), inset 0 0 25px rgba(244, 223, 163, 0.05) !important; | |
| padding: 20px !important; | |
| } | |
| #estado-lectura { | |
| text-align: center; | |
| font-family: 'EB Garamond', serif; | |
| color: #f4dfa3; | |
| font-size: 1.2em; | |
| margin-top: 10px; | |
| min-height: 30px; | |
| } | |
| .boton-capitulo button { | |
| background: linear-gradient(180deg, rgba(40, 35, 90, 0.9), rgba(15, 12, 45, 0.9)) !important; | |
| border: 1px solid rgba(244, 223, 163, 0.4) !important; | |
| color: #f4dfa3 !important; | |
| font-family: 'Cinzel', serif !important; | |
| border-radius: 12px !important; | |
| transition: all 0.25s ease-in-out !important; | |
| } | |
| .boton-capitulo button:hover { | |
| background: linear-gradient(180deg, rgba(90, 70, 160, 0.95), rgba(30, 20, 70, 0.95)) !important; | |
| box-shadow: 0 0 18px rgba(244, 223, 163, 0.5) !important; | |
| transform: translateY(-2px); | |
| } | |
| #boton-principal button { | |
| background: linear-gradient(180deg, #f4dfa3, #c9a24d) !important; | |
| color: #16112e !important; | |
| font-family: 'Cinzel', serif !important; | |
| font-weight: 700 !important; | |
| font-size: 1.15em !important; | |
| border-radius: 14px !important; | |
| border: none !important; | |
| box-shadow: 0 0 25px rgba(244, 223, 163, 0.6) !important; | |
| padding: 14px !important; | |
| } | |
| #boton-principal button:hover { | |
| box-shadow: 0 0 40px rgba(244, 223, 163, 0.9) !important; | |
| transform: scale(1.02); | |
| } | |
| footer { display: none !important; } | |
| """ | |
| with gr.Blocks(css=CSS, title="Génesis · Lectura Sagrada", theme=gr.themes.Base()) as demo: | |
| indice_state = gr.State(0) | |
| gr.HTML( | |
| """ | |
| <div id="titulo-divino">✦ GÉNESIS ✦</div> | |
| <div id="subtitulo-divino">El Libro del Principio — Capítulos 1 al 10, narrados en voz</div> | |
| """ | |
| ) | |
| with gr.Column(elem_classes="panel-celestial"): | |
| reproductor = gr.Audio( | |
| label="Reproductor Sagrado", | |
| interactive=False, | |
| autoplay=False, | |
| value=CAPITULOS[0]["archivo"], | |
| ) | |
| estado = gr.Markdown( | |
| f"📖 Listo para comenzar: **{CAPITULOS[0]['titulo']}**", | |
| elem_id="estado-lectura", | |
| ) | |
| boton_iniciar = gr.Button( | |
| "▶ Iniciar la Lectura Completa del Génesis", | |
| elem_id="boton-principal", | |
| ) | |
| gr.Markdown("### O elige un capítulo:") | |
| with gr.Row(): | |
| botones = [] | |
| for i in range(TOTAL): | |
| b = gr.Button(f"Cap. {i + 1}", elem_classes="boton-capitulo") | |
| botones.append(b) | |
| # Encadenar automáticamente al terminar cada capítulo | |
| reproductor.stop( | |
| fn=al_terminar_capitulo, | |
| inputs=indice_state, | |
| outputs=[reproductor, estado, indice_state], | |
| ) | |
| boton_iniciar.click( | |
| fn=iniciar_todo, | |
| inputs=None, | |
| outputs=[reproductor, estado, indice_state], | |
| ) | |
| for i, b in enumerate(botones): | |
| b.click( | |
| fn=lambda i=i: iniciar_desde_boton(i), | |
| inputs=None, | |
| outputs=[reproductor, estado, indice_state], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |