1 puntos por GN⁺ 1 시간 전 | 1 comentarios | Compartir por WhatsApp
  • El cuello de botella del archivo de video no era la herramienta de edición, sino la imposibilidad de buscar; el enfoque fue convertir clips sin etiquetar en un índice consultable en inglés.
  • Con un diseño local-first, se creó un archivo sidecar .description.md junto a cada clip y se extrajeron en una sola llamada de visión rating, iluminación, ubicación, transcripción, palabras clave y una descripción en prosa.
  • El pipeline unió ffprobe, exiftool, Nominatim, ffmpeg, WhisperX, insightface y un modelo de visión para generar metadatos, GPS, frames, transcripción y embeddings faciales.
  • Una MacBook Pro de 16 pulgadas de 2021 con M1 Max y 64 GB ejecutó Gemma 4 31B Q4 en LM Studio, y durante el procesamiento masivo el swap llegó a un máximo de 50.89 GB.
  • Un esquema estructurado y restricciones con enum redujeron las alucinaciones, y fue posible procesar el volumen grande con el 31B local para luego reevaluar en la nube solo el 10–20% más difícil.

El punto de partida del problema: buscar, no editar

  • Durante casi medio año en Maasai Mara, se fueron acumulando videos grabados con iPhone, DJI Pocket, dron, Nikon Z8 y Ray-Ban Meta, pero la mayoría quedaron sin volver a abrirse.
  • Los canales sociales de Mara Hilltop no se detuvieron por falta de contenido, sino por falta de tiempo de edición durante 3 meses.
  • Con Claude Code y Opus 4.5/4.6, el trabajo de desarrollo ya permitía ejecutar agentes por largos periodos y tareas en paralelo, y al coincidir con el primer lanzamiento de alojamiento pago de KaribuKit, el tiempo para editar video se redujo todavía más.
  • La primera solución imaginada fue un stack SaaS de $140 al mes combinando Eddie AI, Higgsfield MCP, Submagic y Buffer, pero no encajaba con el cuello de botella real.
  • El video generativo con IA no iba con una marca de viajes real, y cuando los huéspedes esperan un lugar real, una escena de IA mal presentada puede dañar la confianza.
  • La frecuencia realista de publicación era más cercana a 2–3 por semana que a 3–5, así que el plan inicial probablemente iba a fallar desde la segunda semana.
  • DaVinci Resolve Studio y las funciones IntelliSearch, Smart Bins y Voice to Subtitle de Resolve 21 ya cubrían alrededor del 70% de lo que ofrecía Eddie.
  • Lo que quedaba era una estructura donde Claude Code controlaba Resolve mediante el MCP open source de DaVinci Resolve y usaba ElevenLabs para voiceover solo en clips informativos, reduciendo el costo a $22 al mes.

El verdadero cuello de botella: antes que un editor con IA, hacía falta un índice

  • Los editores de video con IA del mercado asumen que el video ya está etiquetado, pero el archivo real estaba disperso con nombres como IMG_*.mov, DJI_*.mp4 o Mara june 2024 backup final FINAL.
  • Eddie permitía buscar por transcripción, pero no encontraba escenas como “elefantes sobre una colina en la hora dorada” dentro de un archivo sin etiquetas.
  • Con solo nombre de archivo, carpeta padre, coordenadas GPS y texto transcrito, no se puede saber el contenido visual de algo como “un plano abierto al amanecer con jirafas en el encuadre”.
  • La verdadera palanca no estaba encima del editor, sino antes de él: primero hacía falta un índice que volviera el archivo consultable en inglés.

Diseño del indexador local-first

  • La estructura general se parecía a los builds AI-native para clientes que se hacen en SimbaStack, pero como aquí la misma persona era cliente e ingeniero, las decisiones se tomaban más rápido.
  • Cuatro restricciones

    • Tenía que ser local-first
      • El archivo de Mara Hilltop estaba en SSD físicos y los videos personales en la laptop; subir miles de clips de varios GB a la nube no tenía sentido ni por costo ni por privacidad.
    • Se quería un archivo sidecar en vez de una base central
      • Se colocó un .description.md junto a cada clip para poder usar grep sobre texto plano.
      • Aunque el indexador se rompiera después, los archivos seguirían ahí, y al mover entre discos, los datos se irían con ellos.
    • Había que extraer toda la información necesaria en una sola llamada de visión
      • Como el paso de visión sobre los frames extraídos es caro, el esquema se definió amplio desde el inicio para obtener también lo que pudiera hacer falta más adelante en la primera llamada.
      • Incluía rating, technical quality, lighting, time of day, color palette, audio quality, people count, keywords, faces, location, transcript y una prose description.
    • Debían poder elegirse tres backends de visión
      • El valor por defecto era el CLI de la suscripción Claude Max, sin costo marginal.
      • Cuando hacía falta velocidad, se usaba la API de Anthropic.
      • Para procesamiento masivo, se usó un backend local apuntando a LM Studio, y ese backend local fue la pieza clave.

Pipeline de procesamiento por clip

  • Se leyó el metadata con ffprobe.
  • Con exiftool se leyeron latitud, longitud y altitud GPS, funcionando igual con videos de iPhone, DJI Pocket y dron.
  • Se hizo reverse geocoding con Nominatim, que es gratis, tiene rate limits y no requiere API key.
  • Con ffmpeg se extrajeron 5 frames de 1920 px a intervalos uniformes.
  • Con WhisperX se hizo la transcripción con alineación palabra por palabra y separación de hablantes con pyannote; soporta 97 idiomas, incluidos hindi, inglés y suajili.
  • Con insightface se detectaron rostros y se guardaron embeddings ArcFace de 512 dimensiones en una base SQLite central de rostros para poder buscar personas más adelante en todo el archivo.
  • El modelo de visión leyó los frames, parte de la transcripción y el contexto de la carpeta, y devolvió YAML frontmatter y una descripción en prosa.
  • El resultado final se guardó como sidecar .description.md junto al clip.
  • En el clip real IMG_1103.MOV de Mara Hilltop, el nombre de archivo no daba contexto, pero el sidecar generado por Gemma incluía el montaje de una tienda safari, un paneo de cámara desde interior hacia la sabana, tipo de toma y usos como reel de marketing o B-roll de vlog de viaje.
  • A nivel de carpeta, además de los sidecars junto a cada clip, se generaron _INDEX.json y _INDEX.md para grep rápido y para pasarlos a un LLM.
  • La implementación completa fue una skill de Claude Code de unas 1,400 líneas de Python; Claude Code escribió la mayor parte y la persona se encargó de la arquitectura, los prompts, el diseño del esquema y el bug triage.

Un modelo local 31B corriendo en una MacBook vieja

  • La MacBook Pro de 16 pulgadas con M1 Max y 64 GB de RAM comprada en 2021 no se eligió originalmente para LLM, sino para correr a la vez Chrome, DaVinci Resolve, Slack, Discord y Drive.
  • Cinco años después, esa misma laptop ejecutó Gemma 4 31B Q4 en LM Studio y procesó un año completo de archivo de video.
  • En LM Studio, un modelo de 28.40 GB se cargó en memoria y la API REST corrió en 127.0.0.1:1234.
  • Durante el procesamiento masivo, 64 GB de RAM ya no alcanzaban y el uso de swap según Activity Monitor llegó a 50.89 GB.
  • Ese estado no era sostenible para un día normal de trabajo, pero sí se consideró aceptable para forzar la máquina durante un fin de semana.
  • La laptop se calentaba y los ventiladores sonaban fuerte, pero seguía generando sidecars mientras se hacían otras tareas.
  • La M1 Max de 16 pulgadas mostró suficiente margen para correr un modelo de 31B parámetros a una velocidad usable incluso con hardware de 5 años, y si los LLM locales siguen volviéndose más eficientes, todavía podría servir otros 3–5 años.

Cuatro bugs y sus lecciones

  • Cambio en la API de diarización de WhisperX 3.8

    • En WhisperX 3.8, whisperx.DiarizationPipeline se movió al submódulo whisperx.diarize.
    • El argumento del constructor use_auth_token cambió a token, siguiendo pyannote 3.x.
    • La solución fue la introspección de firma.
    • El script primero probaba token= y, si el constructor lanzaba TypeError, hacía fallback a use_auth_token=.
    • Al invocar librerías de IA que cambian rápido, una llamada defensiva al constructor es un seguro barato.
  • Claude CLI devolvía errores de permisos como si fueran respuestas exitosas

    • En la primera prueba del backend CLI, los 4 sidecars devolvieron el mismo texto: “I need permission to read the image frames...”.
    • El exit code era 0 y la salida no estaba vacía, así que pasaba la validación de éxito del script.
    • En modo no interactivo, si falta --permission-mode bypassPermissions, Claude CLI devuelve el texto de denegación de permisos en el cuerpo de respuesta en lugar del prompt.
    • La solución fue agregar ese flag y añadir una validación defensiva para tratar respuestas cortas con “I need permission” como errores y no como descripciones.
    • Al usar herramientas de IA dentro de scripts, hay fallas silenciosas escondidas en los flujos de permisos no interactivos.
  • Gemma devolvía people_count: "many"

    • El prompt de visión decía integer or the string "many" if >10, así que Gemma en realidad siguió bien la instrucción.
    • El bug no estaba en el modelo, sino en el diseño del esquema.
    • Después se corrigió indicando que debía estimar un entero entre 0 y 99, y las respuestas previas con "many" se convirtieron a la fuerza en el parser.
    • Los campos del esquema no deberían diseñarse como unions tipo int o cierto string; es mejor fijarlos siempre como enteros o siempre como strings para simplificar a los consumidores downstream.
  • Un clip movido de motocicleta fue descartado por error

    • El prompt inicial de cull se parecía más al criterio de un portafolio fotográfico, así que evaluaba motion blur severo, soft focus y shake como cull.
    • Un clip nocturno handheld de una motocicleta grabado durante un viaje por España también quedó marcado para descarte, aunque ese desenfoque era justamente parte de la atmósfera del recuerdo.
    • El criterio de cull se cambió de “grabación imperfecta” a “algo que no es un registro real”.
    • Los descartes se limitaron a clips como tapa de lente, video dentro del bolsillo, tests de 2 segundos o exposiciones completamente quemadas.
    • Un archivo fotográfico debe hacerse cull de forma agresiva, pero los recuerdos en video requieren un cull más generoso; incluso con el mismo esquema, hace falta definir claramente el modo.

Conclusiones sobre esquemas estructurados y modelos locales

  • Las restricciones por enumeración reducen las alucinaciones

    • Gemma 4 E4B describió una foto nocturna de un coworking como “brightly lit, abundant natural light, floor-to-ceiling windows”, aunque afuera se veía una noche completamente oscura.
    • Al darle al 31B un esquema estructurado y obligarlo a elegir entre golden_hour | bright_daylight | overcast | dim_interior | nighttime | mixed | unclear, tanto con thinking-off como con thinking-on recuperó nighttime.
    • En prosa abierta, el modelo puede inventar descripciones falsas, pero en un enum no puede inventar valores nuevos, solo equivocarse al elegir uno.
    • El esquema resultó más seguro que la instrucción.
  • Un 31B local con prompts estructurados reduce la brecha frente a la nube

    • Gemma 4 31B Q4 con thinking-off produjo, usando un esquema estructurado, salidas difíciles de distinguir de Sonnet 4.6 en muchos clips de prueba.
    • La prima de los modelos en la nube sí valía la pena en el 10–20% más difícil.
    • Para trabajo masivo, como indexar miles de clips durante la noche, era escalable correrlo localmente y luego reevaluar en la nube solo los clips que el modelo local marcara como review.
  • Los editores de video con IA compiten en una capa demasiado alta

    • La capa de valor no era el editor, sino el índice consultable.
    • Si se puede consultar en lenguaje natural algo como “clips handheld de interior en Mara, hora dorada, con personas y de más de 8 segundos”, entonces el editor que va encima se simplifica.
    • El mercado de editores de video con IA está compitiendo por una capa superficial montada sobre un índice que no existe, saltándose el prerequisito.

Siguientes pasos y límites

  • El siguiente trabajo es construir un editor usando Claude Code como orquestador, DaVinci Resolve MCP para hacer los cortes y voiceover de ElevenLabs para clips informativos.
  • Hay límites claros para el voice cloning
    • Solo se usaría para contenido utilitario como indicaciones, descripción de habitaciones, versiones multilingües o información factual que la persona realmente diría.
    • No se usaría para reseñas ni mensajes del fundador.
    • En 2026, la legislación sobre obligación de divulgación ya es una realidad, y la confianza en una marca de hospitality se puede perder fácilmente.
  • Con el índice, ya no hace falta scrubbear manualmente 47 GB de video de DJI Pocket para encontrar un plano abierto al amanecer.
  • Ahora, en una laptop de 5 años, un año de video de Mara Hilltop ya se puede consultar en inglés, a cambio de tiempo de fin de semana y 50 GB de swap.
  • Los años restantes que siguen guardados en SSD viejos son el próximo objetivo.
  • Los canales sociales de Mara Hilltop todavía no han revivido
    • El indexador solo resolvió el problema de encontrar clips adecuados.
    • La otra mitad es un editor que los convierta en reels terminados; si funciona habrá una publicación de seguimiento, y si falla se explicará por qué.
  • La respuesta correcta tal vez sea contratar a una persona
    • Encontrar un editor con una sensibilidad cálida y observadora que encaje con Mara Hilltop puede ser más difícil que escribir otra skill.
    • No se busca un reel estilo MTV con cortes excesivos.
  • El código está publicado en github.com/Simbastack-hq/framedex y se aceptan PRs e issues.

1 comentarios

 
GN⁺ 1 시간 전
Comentarios en Hacker News
  • Parece que Claude eligió mal la URL para compartir cuando escribió el post. A menos que la carpeta home esté expuesta al exterior, no se puede acceder a ~/.claude/skills/video-index/, así que me pregunto si podrías compartir el archivo Skill

    • Esto fue como ver una versión moderna de la situación clásica en la que un amigo que recién empieza a programar te manda: “Hice mi web app, ¿la quieres ver? Está aquí: http://localhost:8080”
    • Ups, fue error mío. Lo estoy corrigiendo ahora y también puedo compartir el archivo Skill. Dame 5 minutos
  • Actualización: armé este repositorio a las carreras - https://github.com/Simbastack-hq/framedex
    La licencia es MIT y no he podido probarlo bien después de generalizarlo. Pronto lo revisaré como se debe y agregaré más actualizaciones
    Los dos grandes TODO son: 1) usar este índice y la ayuda de Claude para editar video más rápido en DaVinci Resolve, y 2) ahora solo procesé video, pero quiero ampliarlo para que también pueda entender miles de imágenes fijas de la cámara

  • No me queda claro por qué hace falta tanto swapping. Considerando el ancho de banda de memoria necesario, eso podría acortar bastante rápido la vida útil del SSD
    El modelo cuantizado a 4 bits de Gemma 4 31B debería ocupar alrededor de 19GiB, no 28.4GiB [1]. No suelo meter imágenes tan seguido, así que no sé cuánta memoria extra se necesita al ponerlas en contexto, pero no creo que pase de 10GiB
    En el Monitor de Actividad se ven varias apps de Electron abiertas encima de Handy y de la máquina virtual para Claude Code, que parece ser donde se cargó el modelo, así que probablemente la causa real vaya por ahí. Cuando la laptop empieza a raspar duro el disco, esas apps se van a congelar, así que no parecen muy útiles
    [1] https://huggingface.co/mlx-community/gemma-4-31b-it-4bit

    • Sí. Estaba haciendo otras cosas en la laptop cuando tomé la captura, así que sí había margen para limpiar un poco
      Aun así se trababa un poco, pero me impresionó que podía seguir haciendo otras cosas incluso con un montón de pestañas abiertas en Brave
  • Me pregunto si sabías que esto ya existe, funciona bastante bien y no se traga 50GB de swap
    https://github.com/iliashad/edit-mind

  • Está genial. Ojalá tuviera suficiente RAM para correr modelos locales. En las últimas semanas hice algo muy parecido, pero como una app local de Electron usando Whisper y ffmpeg, y le agregué búsqueda semántica y embeddings para conversar con los videos
    El análisis visual, el etiquetado y el chat con video se comunican con Claude. Me pregunto si este proyecto envía solo una imagen. Yo encuentro varias imágenes distintas por video con un algoritmo personalizado de detección de escenas y se las mando a Claude en una sola solicitud junto con los subtítulos. Definitivamente es la parte más cara. Si usas Sonnet 4.6 para el análisis y Haiku para el etiquetado, sale como 1 dólar por una hora de video, y en local probablemente sería lento

    • No es una sola imagen, sino 5 fotogramas por clip en una sola solicitud junto con parte de los subtítulos. Así que esa parte de meter varios fotogramas y subtítulos a la vez es igual
      Pero la forma de elegir los fotogramas es un punto débil. La detección de escenas sin duda ayudaría y es la prioridad número 1 del roadmap. Me interesa saber si podrías compartir cómo eliges los fotogramas en la detección de escenas
      Decidí no meter búsqueda vectorial y mantenerlo simple con archivos Markdown comunes más portables. Si mueves el SSD, el conocimiento se va con los archivos; no hay un índice que sincronizar, y el texto plano sobrevive más que las herramientas. Aun así, la otra dirección que mencionas también vale la pena explorarla
    • Si quieres bajar costos, podrías probar los modelos de OpenRouter. Gemma 4 31B cuesta 0.12 dólares por millón de tokens de entrada y 0.37 dólares por millón de tokens de salida, mientras que Haiku cuesta 1 dólar por millón de tokens de entrada y 5 dólares por millón de tokens de salida
      También hay otras opciones decentes. Gemini 3.1 Flash Lite es muy bueno para este tipo de trabajo. Gemini 3.5 Flash no. Ese tiene un precio poco atractivo
      https://openrouter.ai/google/gemma-4-31b-it
  • Tengo dos preguntas

    1. Me gustaría saber qué es el índice de búsqueda
    2. En el ejemplo de description.md hay cosas como faces -> cluster_id. Me pregunto si eso viene del índice de rostros de DaVinci Resolve. En colecciones de fotos, información como rostros+nombres y ubicaciones es realmente importante, pero los LLM generales no suelen manejar eso bien
      1. Es solo un archivo sidecar .description.md de texto plano que se coloca junto al video para cada clip
        Más adelante, cuando haces lluvia de ideas con Claude con algo como “quiero hacer un video de las habitaciones premium del lodge”, Claude puede revisar los archivos y entender qué videos podrían servir
        También hay un archivo a nivel raíz de la carpeta que junta descripciones de texto para que sea más fácil buscar. Pegué una imagen de ejemplo en el blog - https://blog.simbastack.com/_media/gvcycx2n.png
      2. No viene de DaVinci Resolve. Framedex es un pipeline independiente y Resolve no participa
        Los rostros vienen de insightface. Los detecta con RetinaFace del paquete open source buffalo_l, y corre localmente en CPU. Detecta y genera embeddings de rostros en fotogramas de muestra de cada clip, y luego escribe filas en ~/.framedex/faces.db
        Siendo sincero, sé que esta parte se está acumulando en una base de datos local, pero todavía no he podido probar bien qué tan bien funciona. Planeo revisarlo en serio pronto
        Más ampliamente, por eso framedex intencionalmente no le deja al LLM el manejo de rostros o ubicaciones. Los rostros se manejan con embeddings de insightface / ArcFace, lo que permite comparaciones determinísticas entre clips. El modelo visual solo da un conteo aproximado de personas, no intenta identificar quién es quién
        Las ubicaciones se manejan con EXIF GPS vía exiftool y geocodificación inversa con Nominatim/OpenStreetMap. No son suposiciones, sino metadatos sólidos
        El LLM solo hace lo que sabe hacer bien: descripción de escenas, ambiente, tipo de toma, palabras clave y calificaciones de archivar/revisar/descartar. Aunque esa última parte de las calificaciones sí es debatible
  • Probé correr Gemma para hacer algo parecido en un ThinkPad de 2015. Por suerte pude ampliar la memoria, porque si no habría sido bastante doloroso
    No les voy a mentir: al correr llama.cpp el ventilador se fue a velocidad máxima. Aun así funcionó y terminé el trabajo

    • La frase “el ventilador va a velocidad máxima” siempre me confunde. Si quieres terminar el cálculo lo más rápido posible, al final vas a generar y expulsar más calor, ¿no?
      A veces parece usarse como metáfora de “está usando el 100% de los recursos”, y probablemente aquí significa eso, pero en otros contextos claramente también lo dicen como una queja real
  • No creo que la mayoría de los hosts de Airbnb estén de acuerdo con la frase “el video generativo con IA no tiene lugar para una marca de viajes real”
    Y la expresión “crucifixión en TripAdvisor” también me hace preguntarme de verdad cómo sobreviven los hosts de Airbnb que publican alojamientos falsos

    • Sinceramente, yo también le he dado muchas vueltas a ese tema. Opero un safari lodge, pero no quiero irme por la ruta del video de IA de baja calidad
      Por otro lado, el video real toma tiempo y vuelve más lento todo el proceso
  • Creo que las aplicaciones de IA B2C tienen una limitación estructural porque es difícil construir contexto personalizado
    Si un modelo local competente pudiera encargarse a gran escala de recopilar contexto, investigar, etiquetar, etc. desde cero, eso sería un gran avance aquí

    • Hice una app de IA B2C totalmente local para cambiar nombres de archivos con base en contexto y es gratis
      Le pasas varias capturas de pantalla e intenta ponerles nombres inteligentes basados en lo que hay dentro. Igual con videos, PDFs, etc.
      Pero sí, como dices, ni siquiera intenté cobrar porque parece el tipo de cosa que Apple simplemente va a meter como función
      https://finalfinalreallyfinaluntitleddocumentv3.com/
    • Totalmente de acuerdo. Aquí Claude y yo hicimos juntos esa investigación y prueba y error mientras hacíamos lluvia de ideas
      Pero creo que es cuestión de tiempo para que los agentes se vuelvan lo bastante inteligentes como para que amigos no técnicos solo digan “ordena estos videos de esta carpeta para que se puedan entender” y lo haga tal cual
    • Me pregunto si de verdad los modelos locales son lo que resuelve esto. ¿No te daría el mismo beneficio una API de modelo que no guarde estado? Entiendo que lo local puede ser “más barato” según el uso, pero llevamos mucho tiempo pagando un premium por rentar almacenamiento y cómputo en la nube