Compare commits

..

1 Commits

Author SHA1 Message Date
rafa 4d25a8d2e5 fea-audio-player: limpiar el aviso de error cuando el audio sí llega a reproducir
Si audio.play() fallaba tras verificar el hash (p.ej. política de autoplay
del navegador tras el await de fetch+digest), el aviso "No se pudo verificar
el audio" quedaba fijo en pantalla aunque el usuario reprodujera el audio a
mano desde los controles nativos que ya estaban visibles. El evento 'play'
real del <audio> ahora limpia ese aviso y oculta el botón, sea cual sea el
camino por el que arrancó la reproducción.

Reportado por Rafa en el canal feadulta, viendo el estado atascado en
"Más allá de la trinchera..." (post 56196) tras el bloqueo 403 de Cloudflare.
2026-08-28 05:29:23 -04:00
3 changed files with 12 additions and 16 deletions
-9
View File
@@ -87,15 +87,6 @@ FEA_TTS_CARTAS="<ID_CARTA>" python3 scripts/tts_produce.py
Reanudable (no repite lo ya hecho, meta `fea_audio_done`) y con freno automático si la cuota de Reanudable (no repite lo ya hecho, meta `fea_audio_done`) y con freno automático si la cuota de
MiniMax se agota (para tras fallos seguidos, no se queda colgado). MiniMax se agota (para tras fallos seguidos, no se queda colgado).
**Alcance del TTS — qué NO llevar a audio (confusión real en la carta 741, 2026-08-26):**
- **Solo el artículo original en español.** Las traducciones (EN/FR/IT/PT) nunca llevan audio
propio — no meter los posts de traducción en la cola (`FEA_TTS_IDS`/`FEA_TTS_CARTAS`).
- **Un audio por artículo, nunca uno combinado de toda la carta.** `tts_produce.py` es correcto
(genera un mp3 por post). No usar `scripts/tts_carta.py` (legacy, concatena todos los artículos
de la carta en un único audio) — no es el flujo que se usa hoy.
- **Nunca la categoría `multimedia`** (término `multimedia`, id 1649 — ver
`scripts/aplicar_clasificacion_a_bd.py`). Esas piezas no se locutan.
**Publicar el audio en prod** (el paso anterior solo escribe en el WordPress local): **Publicar el audio en prod** (el paso anterior solo escribe en el WordPress local):
```bash ```bash
python3 scripts/sync_audio_to_prod.py --carta <ID_CARTA> python3 scripts/sync_audio_to_prod.py --carta <ID_CARTA>
+12
View File
@@ -125,6 +125,18 @@ add_action('wp_footer', function () {
document.querySelectorAll('audio[data-fea-audio-track]').forEach(function (audio) { document.querySelectorAll('audio[data-fea-audio-track]').forEach(function (audio) {
var fired = false; var fired = false;
audio.addEventListener('play', function () { audio.addEventListener('play', function () {
// La verificación pudo fallar en el primer intento (p.ej. audio.play()
// rechazado por política de autoplay tras el await de verificación) y
// dejar el mensaje de error en pantalla. Si el audio realmente rompe a
// reproducir -en este intento o en uno posterior desde los controles
// nativos-, ese es el estado real: limpiar el aviso y ocultar el botón.
var wrap = audio.closest('.fea-audio');
if (wrap) {
var status = wrap.querySelector('.fea-audio-status');
if (status) status.textContent = '';
var button = wrap.querySelector('[data-fea-audio-verified-play]');
if (button) button.hidden = true;
}
if (fired || typeof gtag !== 'function') return; if (fired || typeof gtag !== 'function') return;
fired = true; fired = true;
gtag('event', 'audio_play', { gtag('event', 'audio_play', {
-7
View File
@@ -187,13 +187,6 @@ def save_state(state: dict) -> None:
# ── Sync ───────────────────────────────────────────────────────────────────── # ── Sync ─────────────────────────────────────────────────────────────────────
def sync_one(post_id: int, state: dict, *, dry_run: bool) -> str: def sync_one(post_id: int, state: dict, *, dry_run: bool) -> str:
# issue #190: páginas de cuentas/donaciones (ej. #18036 "numeros") llevan
# fea_audio_skip=1 desde el hotfix del 3-ago, pero pueden conservar un
# fea_audio_done=1 y un mp3 locales obsoletos de antes del guard. Sin este
# chequeo, cualquier --carta cuyo cluster las incluya vuelve a publicar el
# audio improcedente en prod (nos pasó el 26-ago con la carta 741).
if local_meta(post_id, "fea_audio_skip") == "1":
return "excluido (fea_audio_skip)"
if local_meta(post_id, "fea_audio_done") != "1": if local_meta(post_id, "fea_audio_done") != "1":
return "sin-audio-local" return "sin-audio-local"
if not (LOCAL_TTS_DIR / f"{post_id}.mp3").exists(): if not (LOCAL_TTS_DIR / f"{post_id}.mp3").exists():