Parte III — Ramas, savia y semillas

07 · La savia: enriquecimiento

La savia sube de la raíz a las hojas sin que nadie la vea. El enriquecimiento hace eso con los anexos: saca texto de los PDF, reconoce páginas escaneadas, escribe subtítulos de lo que se habla — para que la búsqueda encuentre y quien no oye pueda leer.

Archivos para leer

  1. docs/baobaxia-enriquecimento.md — el diseño completo (léelo antes).
  2. enriquecimento/servico.py — Enriquecedor: decidir, ejecutar, grabar.
  3. enriquecimento/procedencia.py — el registro de "qué se hizo con qué archivo, con qué motor, con qué resultado" (data.enriquecimento).
  4. enriquecimento/classificar.py, textos.py, ocr.py, transcricao.py, legendas.py, vocabulario.py.
  5. infra/previa_video.py, infra/thumbnails.py, infra/mosaico.py.

Qué es automático y qué se pide

AutomáticoSolo a pedido (por archivo)
Texto de PDF, docx, odt, txt, html✅ (caché local)
Vista previa de la barra de video✅ (caché local)
Transcripción con Whisperdata.transcrever: [archivos]
OCR con Tesseractdata.ocr: [archivos]

El pedido viaja con el sync: quien pide puede ser una mucua sin Whisper; la próxima mucua con la capacidad y con el archivo hace el trabajo, y el subtítulo vuelve a todas como anexo (<archivo>.<idioma>.vtt, en el annex).

flowchart TD
    A[anexo en content] --> B{¿ya hay registro de procedencia<br/>con el mismo hash?}
    B -- sí --> C{¿--forcar, o mejor modelo aquí<br/>y salida no revisada por personas?}
    C -- no --> Z[salta]
    C -- sí --> D
    B -- no --> D[clasificar]
    D -->|audio/video| E{¿está en data.transcrever?}
    E -- no --> Z
    E -- sí --> E2[ffmpeg 16 kHz → Whisper + VAD + vocabulario<br/>→ archivo.pt.vtt en el annex]
    D -->|PDF| F[pdftotext → caché local]
    F --> F2{¿páginas sin texto?}
    F2 -- sí, sin pedido --> F3[status: precisa_ocr]
    F2 -- sí, con data.ocr --> G[Tesseract → archivo.ocr.txt en el annex]
    D -->|imagen| H{¿está en data.ocr?}
    H -- sí --> G
    H -- no --> Z
    D -->|docx/odt/txt/html| I[texto → caché local]

Cuidados que tiene el código

  • Traba de proceso (_TravaProcesso): solo una ronda por máquina; otra responde ja_em_andamento.
  • Traba de la galaxia: espera a que el sync y los pedidos la suelten (ESPERA_TRAVA).
  • Interrupción limpia (_SemInterrupcao): un Ctrl-C en medio de la grabación espera a que termine el commit, para no dejar el .bbx a medias.
  • La revisión humana gana: foi_revisada compara el hash registrado con el del subtítulo actual. Si alguien corrigió el subtítulo, la máquina no escribe encima.
  • Intentos limitados ante errores (MAX_TENTATIVAS), y un error de entorno (motor ausente) no gasta intentos.

Prácticas

  1. Lee test_enriquecimento_whisper.py::test_transcricao_so_dos_arquivos_marcados y explica por qué no se transcribe todo video.
  2. Con ffmpeg instalado, genera un video corto, publícalo, márcalo en data.transcrever y corre bbx enriquecer --saber <uuid>. ¿Dónde aparece el subtítulo en el disco? ¿Y en el índice?
  3. En procedencia.py, sigue precisa_processar. ¿En qué caso un modelo más grande rehace el subtítulo?
  4. Agrega nombres de lugares de tu comunidad al vocabulario de un saber (data.vocabulario) y compara la transcripción.

Para conversar

  • Un subtítulo hecho por máquina en una lengua indígena o en un habla quilombola se equivoca. ¿Cómo da lugar el diseño del sistema a la corrección hecha por la comunidad?

vedi questo capitolo come sapere