Película cinética a DaVinci Resolve
Convierte el spec.js de una película cinética en una línea de tiempo de Resolve donde cada toma es un clip con su propia composición Fusion: Text+ y Text3D reales, cámaras con fotogramas clave, la misma sincronización de compás. Un editor puede entonces abrir cualquier toma en la página Fusion, volver a escribir una palabra, recortarla o cambiar la música.
Es una reconstrucción con las herramientas de Resolve, no una coincidencia de píxeles. Di qué cambió respecto al original (setup devuelve la lista como notes) e infórmaselo al usuario.
Antes de empezar
- Resolve Studio se está ejecutando con un proyecto abierto. Compruébalo con
get_resolve_statusy llama aget_whats_newuna vez, como lo pide el servidor de Resolve. - La carpeta de la película tiene
spec.jsy los archivos del motor, connpm install playwrightejecutado en ella. - Python con Pillow fuera de Resolve, para medir el tipo. ffmpeg en PATH.
Pregunta al usuario
Decide esto antes de construir, a partir de la conversación si puedes:
- Qué proyecto. La línea de tiempo se añade al proyecto abierto. Indica al usuario cuál es. Cambiar de proyecto podría descartar su trabajo no guardado, así que pídele que cambie si es el incorrecto.
- Nombre de la línea de tiempo. Por defecto
<título> (Fusion). Revisa las líneas de tiempo existentes y elige un nombre que esté libre. Nunca reutilices ni reemplaces una que no hayas construido en esta sesión. - Fuente. Text+ solo ve fuentes instaladas, y la Archivo de la película generalmente no lo está. Usa la fuente de la marca si el proyecto muestra una. Llama a
fonts_available(resolve, 'Lato', 'Inter')para comprobarlo; no instales fuentes sin preguntar. Los pesos gruesos se leen mejor: Black, Heavy, ExtraBold. - Audio. Una edición de música de una línea de tiempo existente (
audio_from_timeline), un archivo (audio_from_file) o ninguno. Si una línea de tiempo ya contiene esta película con música, ofrécelo primero, porque conserva la edición del usuario.
Pasos
SKILL a continuación es la carpeta de esta skill y F es la carpeta de la película. Cada paso de Resolve pasa por run_script_unsafe, que está limitado a 60 s por llamada, y comienza con:
SKILL = r'<carpeta de esta skill>'; F = r'<carpeta de la película>'
exec(open(SKILL + r'\scripts\resolve_build.py', encoding='utf-8').read())
1. Exporta la especificación (desde un shell):
node "<SKILL>/scripts/export_film.mjs" "<F>"
Escribe <F>/resolve/film.json y el logo como PNGs transparentes, e imprime los bloques que encontró.
2. Crea la línea de tiempo:
result = setup(resolve, project, F, 'Mi Película (Fusion)', 'Lato', 'Black', 'Inter', 'Medium')
Las dos últimas fuentes son para líneas pequeñas y UI simulada. Crea la línea de tiempo, un contenedor Kinetic Films / <título> y un clip placeholder negro, y devuelve el número de tomas y notes. El tamaño y la frecuencia de imagen de la línea de tiempo provienen del proyecto, por lo que una película hecha a 60 fps puede aterrizar en una línea de tiempo de 30 fps. Solo está probado en 1920x1080, 60 fps, así que revisa bien otros formatos.
3. Mide el tipo (desde un shell, usando un Python que tenga Pillow):
python "<SKILL>/scripts/measure_fonts.py" "<F>" Lato Black
Sin ello, las palabras usan anchos estimados y pueden no llenar bien el fotograma. Si informa que no hay archivo de fuente, continúa y verifica el encuadre de cerca.
4. Construye. Repite hasta que done sea true; se reanuda donde se detuvo:
result = build_batch(project, F, 40)
Luego añade el HUD (solo si la película lo tiene), el audio y los marcadores de escena:
result = dict(hud=add_hud(project, F), audio=audio_from_timeline(project, F, 'Music Edit'), markers=add_markers(project, F))
El HUD es un clip Fusion en la pista 2 sobre toda la película. Un editor puede deshabilitar ese clip para eliminarlo.
5. Revisa fotogramas. En Resolve 21.2 o posterior, esto exporta hojas etiquetadas del medio de cada toma directamente desde la línea de tiempo en unos segundos, sin renderizar y sin cambiar la configuración de renderizado. Van a <F>/resolve/review/. Verifica que nada esté negro, las palabras permanezcan en el fotograma, los kickers despejen sus palabras y las imágenes cubran el fotograma. Corrige lo que esté mal antes de renderizar. frame_grid(project, F, seconds=[4.2, 9.35]) da momentos elegidos a tamaño completo, como el final de un whip.
result = frame_grid(project, F)
Los fotogramas coinciden con un renderizado del mismo fotograma, verificado en 21.2. En un Resolve más antiguo sin ExportThumbnails, genera un error, así que juzga a partir del renderizado.
6. Renderiza y mide el movimiento.
result = start_render(project, F, 'my_film') # elige un codificador H.264 de GPU cuando hay uno
# en llamadas posteriores: result = wait_render(project, result_job_id, 50)
Espera aproximadamente 2 a 4 minutos para 30 s a 1080p60 en una GPU potente. Después, elimina solo tu propio trabajo con remove_job. La cola puede contener trabajos del usuario. start_render cambia la configuración de renderizado del proyecto, así que dilo.
El movimiento solo se puede medir desde el video. Ejecuta holds.py y dyn.py de los scripts de scenario-kinetic-film sobre el renderizado, si están instalados. Los objetivos son 40 % de fotogramas fijos o menos, ninguna pausa mayor a 0.6 s antes de la tarjeta final, y una mediana de movimiento de 2.5 o más. Informa los números, incluyendo fallos.
Para cambiar algo, arréglalo y reconstruye con setup(..., replace=True), solo en una línea de tiempo que esta skill haya construido, luego repite los pasos 4 a 6. Para una corrección de unas pocas tomas, rebuild_shots(project, F, [8.2, 13]) reemplaza solo las composiciones de las tomas en esos tiempos (en segundos), o por índice de toma, y mantiene todo lo demás. Si las palabras de la película cambiaron, vuelve a ejecutar el paso 3.
7. Finaliza. Deja el guardado al usuario a menos que lo pida: guardar también confirma cualquier otra edición no guardada que tenga abierta. Informa el nombre de la línea de tiempo, las notas, el tiempo de renderizado y los números de revisión. Menciona que el clip placeholder debe permanecer en su contenedor, o las tomas podrían mostrarse como fuera de línea.
Lo que no debes hacer, y por qué
Cada uno de estos cuesta tiempo real de encontrar. El detalle está en references/fusion-traps.md; léelo antes de cambiar fusion_lib.py o si algo sale mal.
- No bloquees una composición mientras la construyes. El clip entonces se renderiza negro. Bloquea solo alrededor de la creación del Loader, como lo hace
Shot.loader; de lo contrario, establecer el clip del Loader abre un selector de archivos modal en la pantalla del usuario que detiene todo el scripting. - No uses
ExportCurrentFrameAsStillpara revisar. Supera a Fusion y devuelve fotogramas negros o desactualizados.frame_grid, que usaTimeline.ExportFrameyExportThumbnails, es confiable, pero solo en la línea de tiempo actual: una línea de tiempo que no se ha abierto exporta fotogramas negros mientras aún informa éxito. - No acumules desenfoque de movimiento. El desenfoque en el movimiento propio de una palabra y en la cámara multiplica el trabajo. Solo la cámara se desenfoca, y solo durante movimientos rápidos.
- No asumas que un codificador más rápido arregla un renderizado lento. La generación de fotogramas Fusion suele ser el límite. Mide antes de cambiar la configuración.
Referencia
- references/block-map.md: cómo se convierte cada uno de los 14 bloques y qué se aproxima. Léelo si una película usa Graph, Counters, Progress, Chain, Prompt, Notes o Rewind, o si el usuario pregunta qué tan cerca estará una toma.
- references/fusion-traps.md: comportamiento de la API descubierto a las malas, y cómo recuperar un Resolve atascado.