Skip to main content

Batch Processing com FFmpeg

Processar um arquivo é simples. Processar 50 arquivos ao mesmo tempo, com a mesma configuração, sem tocar em cada um, é onde o FFmpeg realmente brilha.

Loop simples no terminal

Script Python para batch com mais controle

import subprocess
import os
import glob
from pathlib import Path
def convert_to_mp4(input_dir, output_dir, crf=18):
Path(output_dir).mkdir(parents=True, exist_ok=True)
files = glob.glob(os.path.join(input_dir, '*.mov'))
print(f"Encontrados {len(files)} arquivos.")
for i, f in enumerate(sorted(files), 1):
name = Path(f).stem
output = os.path.join(output_dir, f"{name}.mp4")
cmd = [
'ffmpeg', '-i', f,
'-c:v', 'libx264', '-crf', str(crf),
'-preset', 'slow', '-pix_fmt', 'yuv420p',
'-c:a', 'aac', '-b:a', '192k',
'-movflags', '+faststart', output
]
print(f"[{i}/{len(files)}] {name}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f" ERRO: {result.stderr[-200:]}")
else:
orig = os.path.getsize(f) / (1024*1024)
out = os.path.getsize(output) / (1024*1024)
print(f" OK: {orig:.1f}MB -> {out:.1f}MB")
convert_to_mp4('/renders/master_files', '/renders/web_delivery')

Sequências de render para vídeo

import subprocess, glob, re, os
from pathlib import Path
def sequence_to_video(frames_dir, output_file, fps=24):
files = sorted(glob.glob(os.path.join(frames_dir, '*.png')))
if not files:
files = sorted(glob.glob(os.path.join(frames_dir, '*.jpg')))
print(f"Encontrados {len(files)} frames.")
# Detecta padrão de numeração
first = os.path.basename(files[0])
match = re.search(r'(\d+)', first)
num_digits = len(match.group(1))
prefix = first[:match.start()]
ext = os.path.splitext(first)[1]
pattern = os.path.join(frames_dir, f"{prefix}%0{num_digits}d{ext}")
subprocess.run([
'ffmpeg', '-framerate', str(fps), '-i', pattern,
'-c:v', 'libx264', '-crf', '18', '-pix_fmt', 'yuv420p',
output_file
], check=True)
print(f"Vídeo criado: {output_file}")
sequence_to_video('/renders/my_animation', '/renders/my_animation.mp4')

Processamento paralelo

Terminal window
# Mac/Linux: processa 4 ao mesmo tempo com xargs
ls *.mov | xargs -P 4 -I{} bash -c 'ffmpeg -i "{}" -c:v libx264 -crf 18 "{}.mp4"'
# Python com multiprocessing
import subprocess
import glob
from concurrent.futures import ProcessPoolExecutor
def converter(arquivo):
saida = arquivo.replace('.mov', '.mp4')
subprocess.run(['ffmpeg', '-i', arquivo, '-c:v', 'libx264', '-crf', '18', saida])
return saida
arquivos = glob.glob('*.mov')
with ProcessPoolExecutor(max_workers=4) as executor:
resultados = list(executor.map(converter, arquivos))

Verificando resultado em batch

import subprocess, json, glob, os
def check_videos(folder):
for video in sorted(glob.glob(os.path.join(folder, '*.mp4'))):
cmd = ['ffprobe', '-v', 'quiet', '-print_format', 'json',
'-show_streams', '-show_format', video]
data = json.loads(subprocess.run(cmd, capture_output=True, text=True).stdout)
vs = next(s for s in data['streams'] if s['codec_type'] == 'video')
dur = float(data['format']['duration'])
print(f"{os.path.basename(video):40} | "
f"{vs['width']}x{vs['height']} | "
f"{vs['codec_name']:6} | {dur:.1f}s")

Tip

Comando útil antes de rodar batch: ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1 arquivo.mp4 verifica se o arquivo está íntegro sem ter que abrir.