Por qué tu Previsualización de Video Miente sobre la Exportación
Tu editor de video parece terminado. La previsualización es nítida, el subtítulo se encuentra exactamente donde el usuario lo arrastró, y la línea de tiempo se desplaza suavemente. Luego, el usuario presiona Export, y el subtítulo reaparece en el lugar equivocado, con el tamaño incorrecto, a veces recortado completamente del borde. Nada se bloqueó, no hay errores en el log — la previsualización y el archivo simplemente no coinciden.
Este es el error más común en cada editor de video, y es un problema de modelado de datos más que uno de renderizado. A continuación, se presenta el hábito que hace imposible el error, cómo dimensionar los fotogramas correctamente a partir de una relación de aspecto, y cómo mantener el arrastre rápido en teléfonos económicos. Las ideas se aplican en cualquier lenguaje o UI framework.
La Relación de Aspecto es una Forma, la Resolución es un Tamaño
La mayoría de los errores de fotogramas comienzan aquí. Una relación de aspecto describe la forma del fotograma y nada más: 9:16 es vertical, 16:9 es horizontal. Una resolución describe el tamaño en píxeles, como 1080x1920. Una forma admite muchos tamaños, por lo que los dos valores nunca son intercambiables.
| Relación de aspecto | Valor numérico | Uso típico |
| 16:9 | 1.78 | YouTube, web horizontal |
| 9:16 | 0.56 | Reels, TikTok, Shorts |
| 1:1 | 1.00 | Publicaciones cuadradas en el feed |
| 4:5 | 0.80 | Publicaciones verticales en el feed |
Almacena la relación como texto plano y conviértela a un número solo cuando hagas cálculos. Almacena una altura objetivo para la exportación, luego deriva el ancho a partir de la relación y fuerza a que ambos números sean pares antes de que lleguen a un codificador. Las dimensiones impares son la causa silenciosa de un sorprendente número de exportaciones fallidas.
height = width / ratioToNumber(ratio) // dimensionando la caja de previsualización
function widthFromHeight(ratio, height): raw = height * ratioToNumber(ratio) return makeEven(round(raw)) // los codificadores requieren lados pares
// 9:16 con 1080 de alto -> 608 x 1080// 16:9 con 1080 de alto -> 1920 x 1080
Almacena Posiciones como Fracciones, Nunca como Píxeles
Un editor vive en tres mundos con tres tamaños diferentes: el documento guardado, la previsualización en pantalla y el archivo exportado. El documento es la única fuente de verdad — los otros dos son solo representaciones del mismo a una escala diferente.
Project -> Clip (source, trim, filters) -> Overlay (text / sticker)
Document Renderizador de previsualización Renderizador de exportación x = 0.5, y = 0.9 --> x * 360 px --> x * 1080 px --> MP4 | ^ ^ +------------------------+------------------------+ una fracción almacenada, una fórmula, dos tamaños
Si almacenas 540 píxeles, ese número solo es correcto en el dispositivo en el que se midió. Si almacenas 0.5, significa "el centro horizontal" en cada tamaño para siempre. Cada posición, desplazamiento y escala en el modelo debe ser una fracción entre 0 y 1.
type Overlay { x: number // 0.0-1.0 horizontal (0.5 = centro) y: number // 0.0-1.0 vertical (0.9 = cerca del fondo) scale: number // 1.0 = tamaño normal rotation: number // grados startTimeMs: number // cuando aparece endTimeMs: number // cuando desaparece}
La exportación se vuelve casi aburrida, que es el objetivo. El renderizador utiliza la misma fórmula que la previsualización con un multiplicador mayor: px = overlay.x * exportWidth. FFmpeg maneja el fotograma en sí, y su expresión de centrado (ow-iw)/2 es la misma aritmética que la previsualización usa para el letterbox. Debido a que el valor almacenado nunca cambió, el subtítulo aterriza exactamente en el lugar correcto.
ffmpeg -i input.mp4 \ -vf "scale=1080:1920:force_original_aspect_ratio=decrease,\ pad=1080:1920:(ow-iw)/2:(oh-ih)/2:0xD3D3D3" \ -c:v libx264 -crf 23 -pix_fmt yuv420p -c:a aac output.mp4
Dibuja la Previsualización en una Sola Pasada
Mide el recuadro de previsualización en tiempo de ejecución en lugar de codificarlo de forma fija, ya que un teléfono, una tableta y una ventana de escritorio redimensionada te darán un tamaño diferente. Dibuja cada overlay en una sola pasada de canvas en lugar de montar cada uno como un elemento UI separado — una sola pasada se mantiene fluida mientras un dedo se mueve.
Dos reglas mantienen el bucle honesto. Omite cualquier overlay fuera de su rango de tiempo, y siempre empareja save() con restore() para que un elemento no pueda filtrar su transformación al siguiente.
function drawPreview(canvas, overlays, currentTime, box): para cada overlay en overlays: if currentTime < overlay.startTimeMs: omitir if currentTime > overlay.endTimeMs: omitir
px = overlay.x * box.width // la fórmula clave py = overlay.y * box.height
canvas.save() canvas.move(px, py) canvas.rotate(overlay.rotation) canvas.resize(overlay.scale) canvas.drawText(overlay.content) canvas.restore() // nunca opcional
Mantén el Arrastre Fluido con un Estado de Dos Niveles
Un dedo que arrastra reporta aproximadamente sesenta posiciones por segundo. Si cada una escribe en tu almacén de proyectos, pagas por la validación, la persistencia y una reconstrucción completa del estado sesenta veces por segundo, y el arrastre tartamudea visiblemente. Divide el trabajo en dos niveles en su lugar:
- Nivel 1, efímero: un pequeño mapa
liveDragque contiene la posición actual del dedo. Actualízalo en cada movimiento y repinta el canvas. Nada más se ejecuta. - Nivel 2, duradero: al finalizar el arrastre, guarda la fracción final en el overlay del modelo del proyecto, borra la entrada de
liveDragy registra un paso de undo.
El beneficio va más allá de la tasa de fotogramas. El historial de undo se mantiene útil porque un arrastre produce una entrada en lugar de cientos, y el guardado automático deja de saturar el disco. Así es como Figma y Canva mantienen la manipulación directa responsiva.
Contexto del Mundo Real
En MicrocosmWorks, tomamos un editor de formato corto cuyos subtítulos se desajustaban en la exportación. El equipo había persistido las posiciones del overlay como píxeles del dispositivo leídos directamente del canvas de previsualización, por lo que un subtítulo creado en un teléfono pequeño aparecía alto y pequeño en el archivo 1080p, y al cambiar la relación de aspecto algunos overlays salían completamente del encuadre.
Migramos el modelo a coordenadas normalizadas de 0 a 1, hicimos que ambos renderizadores compartieran un único helper de fracción por tamaño, y forzamos dimensiones de salida pares derivadas de la relación almacenada. La previsualización y la exportación coincidieron en cada dispositivo de prueba. Mover los 'drag commits' al 'drag-end' eliminó el retraso que los usuarios habían reportado en hardware Android de gama baja. Puedes ver el tipo de video de formato corto y el trabajo de edición del que provino esto en nuestro portfolio de proyectos.
Conclusión
Una previsualización y una exportación son dos representaciones de un mismo documento, así que dales una única fuente de verdad. Almacena las posiciones como fracciones, utiliza la misma fórmula de fracción por tamaño en ambos renderizadores, deriva el ancho de la relación de aspecto, mantén las dimensiones pares y confirma los cambios de arrastre solo cuando el dedo se levante. Esos cinco hábitos eliminan una categoría completa de errores antes de que se escriban.
Construir motores de medios donde la vista interactiva y el archivo final coincidan es un enfoque central de nuestro trabajo de ingeniería de video y streaming en MicrocosmWorks.
¿Estás lanzando un editor de video o contenido y quieres que la previsualización y la exportación realmente coincidan? Hemos resuelto esta clase exacta de errores en herramientas de edición de formato corto. Habla con nuestro equipo de ingeniería →
Lee más de nuestro equipo
1. Optimizando el Logotipo del Canal para Diferentes Resoluciones de Video
2. Toma una Foto de un Plato, Registra una Comida: Un Pipeline de Nutrición con Visión por Computadora
3. Optimizando el Logotipo del Canal para Diferentes Resoluciones de Video

