Sitios cinematográficos|INEMA.CLUB-PRO

Clase 2 · 15 min

Del video a los cuadros: extraer, comprimir y ordenar la secuencia

La calidad del movimiento en el scroll se decide aquí. Pocos cuadros y la película se vuelve diapositivas; cuadros grandes y la página no abre en el celular; nombres sin ceros y la película salta. Haces un clip de ensayo con ffmpeg a partir de una foto, extraes todos los cuadros y revisas cantidad, orden y peso con un script.

Comenzar la clase
Tira de negativos de cine sobre una mesa de luz, con una lupa encima.

En esta clase vas a

  1. 1Un clip de ensayo a partir de una foto, sin generador
  2. 2Extraer todos los cuadros, a la tasa del clip, con el ancho y la calidad elegidos
  3. 3Por qué f_0001.jpg y no f_1.jpg, y qué hace el manifest.json
  4. 4Revisar cantidad, orden y peso antes de llevarlo a la página

Objetivo: convertir un clip en cuadros a la tasa nativa, con nombres en orden y peso verificado, listos para el scroll.

01Del clip a la carpeta que lee la página

Haz clic en cada etapa.

Haz clic en cada bloque del diagrama para ver qué hace.

Regla de las dos skills de INEMA: extraer a la tasa nativa. Una película de 72 s a 24 cuadros por segundo tiene 1.728 cuadros; sacar "unos 300" se vuelve 4 cuadros por segundo en el scroll (scroll-film-studio, references/engine.md).

02Un clip de ensayo, sin generador

6 s, 24 cuadros por segundo, con la cámara yendo de 1,0 a 1,35 de zoom sobre la foto de la lente del kit.

Terminal · hacer el clip de ensayo
K=~/projetos/formacao-cinema-ia-sites-v72/kit
E=${TMPDIR:-/tmp}/ensaio-sites/a2; rm -rf "$E"; mkdir -p "$E"
bash "$K/scripts/clipe.sh" "$K/exemplos/lente.jpg" "$E/clipe.mp4" 6 1.0 1.35
Ejemplo del repositorio
clipe.mp4: 6,0 s · 24 fps · 1920×1080

Cambia la foto por la de tu producto y tendrás un clip para practicar todo el camino sin gastar nada.

03Extraer y revisar

El quadros.sh extrae; el conferir-quadros.py compara la carpeta con el clip.

Terminal · extraer los cuadros y comprobar
K=~/projetos/formacao-cinema-ia-sites-v72/kit
E=${TMPDIR:-/tmp}/ensaio-sites/a2
bash "$K/scripts/quadros.sh" "$E/clipe.mp4" "$E/quadros" 1024 6
ls "$E/quadros" | head -3
python3 "$K/scripts/conferir-quadros.py" "$E/quadros" "$E/clipe.mp4"; echo "saída: $?"
Archivo · kit/scripts/quadros.sh
#!/usr/bin/env bash
# quadros.sh — extrai TODOS os quadros de um clipe, na taxa nativa dele, para o site rolar.
# Uso: bash quadros.sh <clipe.mp4> <pasta> [largura=1024] [qualidade=6]
#   largura: 1024–1280 px no computador, 720 px no filme vertical do celular.
#   qualidade: -q:v do JPEG (2 = melhor e mais pesado, 31 = pior); 5–6 é o ponto do curso.
# Grava <pasta>/f_0001.jpg, f_0002.jpg… (zeros à esquerda: a ordem alfabética é a ordem do filme)
# e <pasta>/manifest.json {count, fps, largura}, que a página lê para saber quantos quadros pedir.
set -euo pipefail
CLIPE=$1; PASTA=$2; LARG=${3:-1024}; Q=${4:-6}
FPS=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of csv=p=0 "$CLIPE" | python3 -c "import sys; n,d=sys.stdin.read().strip().split('/'); print(round(int(n)/int(d)))")
mkdir -p "$PASTA"; rm -f "$PASTA"/f_*.jpg
# -fps_mode passthrough: um JPEG por quadro do clipe, sem duplicar nem pular.
ffmpeg -v error -i "$CLIPE" -vf "scale=${LARG}:-2" -fps_mode passthrough -q:v "$Q" "$PASTA/f_%04d.jpg"
python3 - "$PASTA" "$FPS" "$LARG" <<'PY'
import glob, json, os, sys
from PIL import Image
pasta, fps, larg = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
q = sorted(glob.glob(os.path.join(pasta, 'f_*.jpg')))
json.dump({'count': len(q), 'fps': fps, 'largura': larg}, open(os.path.join(pasta, 'manifest.json'), 'w'))
w, h = Image.open(q[0]).size
mb = f"{sum(os.path.getsize(f) for f in q) / 1e6:.1f}".replace('.', ',')
print(f"QUADROS: {len(q)} · {w}×{h} · {mb} MB · {fps} fps")
PY
Ejemplo del repositorio
QUADROS: 144 · 1024×576 · 1,5 MB · 24 fps
f_0001.jpg
f_0002.jpg
f_0003.jpg
OK: 144 quadros · 24 fps · 1024 px · 1,5 MB
saída: 0

144 cuadros = 6 s × 24. La carpeta pesa 1,5 MB con 1024 px y -q:v 6.

04Los dos errores que más arruinan la película

Pocos cuadros y nombres sin ceros. Los dos pasan desapercibidos si solo miras la carpeta.

Terminal · extraer mal a propósito
K=~/projetos/formacao-cinema-ia-sites-v72/kit
E=${TMPDIR:-/tmp}/ensaio-sites/a2; mkdir -p "$E/poucos" "$E/sem-zero"
# error 1: "unos pocos cuadros por segundo bastan" (6 por segundo de un clip de 24)
ffmpeg -v error -i "$E/clipe.mp4" -vf "fps=6,scale=1024:-2" -q:v 6 "$E/poucos/f_%04d.jpg"
python3 "$K/scripts/conferir-quadros.py" "$E/poucos" "$E/clipe.mp4"; echo "saída: $?"
# error 2: nombre sin ceros a la izquierda (f_%d en vez de f_%04d)
ffmpeg -v error -i "$E/clipe.mp4" -vf "scale=1024:-2" -q:v 6 "$E/sem-zero/f_%d.jpg"
python3 "$K/scripts/conferir-quadros.py" "$E/sem-zero" "$E/clipe.mp4"; echo "saída: $?"
Ejemplo del repositorio
FALHA: 36 quadros = 6 fps (fonte 24): esperava 144
FALHA: sem manifest.json
saída: 1
FALHA: nomes sem zeros à esquerda (f_109.jpg vem antes de f_11.jpg na ordem alfabética)
FALHA: sem manifest.json
saída: 1

Los dos terminan con código 1. El verificador también exige el manifest.json, que solo quadros.sh escribe.

05Práctica

Del clip a la carpeta comprobada, y una versión tuya.

E1 · Clip de ensayo

5 min

Ejecuta el bloque "hacer el clip de ensayo".

Listo cuando: clipe.mp4: 6,0 s · 24 fps · 1920×1080.

E2 · Cuadros comprobados

5 min

Ejecuta el bloque "extraer los cuadros y comprobar".

Listo cuando: OK: 144 quadros · 24 fps · 1024 px y saída: 0.

E3 · Tu foto

15 min

Haz un clip de 8 s con una foto tuya (bash clipe.sh sua-foto.jpg seu.mp4 8), extrae a 1280 px con -q:v 5 y comprueba. Anota el peso de la carpeta.

Listo cuando: El verificador responde OK: 192 quadros · 24 fps · 1280 px con saída: 0.

06Prueba de la clase

La explicación aparece después de tu respuesta.

Pregunta 1 de 4

Un clip de 6 s a 24 cuadros por segundo. ¿Cuántos cuadros debe tener la carpeta?

07En tres frases

Tasa nativaUn JPEG por cuadro del clip; para que pese menos, ajusta el ancho y -q:v.
Ordenf_0001.jpg con ceros a la izquierda y manifest.json con el conteo.
Revisarconferir-quadros.py antes de llevar a la página.

Para ir más allá

Clase anteriorPróxima clase