Pipeline de edición de vídeo con Blender VSE
Automatiza la edición de vídeo en el Video Sequence Editor de Blender mediante scripts Python ejecutados desde la terminal. Permite ensamblar clips, añadir transiciones, aplicar efectos, superponer texto y renderizar el resultado sin abrir la interfaz gráfica.
Descarga abierta · sin registro · para Blender, Python, FFmpeg
""" CULTIVA IA — Agency Reel 2026 Pipeline de edición de vídeo headless con Blender VSE
Uso: blender --background --python resultado.py
Requisitos: Blender 3.0+ | bpy | FFmpeg
Estructura de archivos esperada: raw/ intro_logo.mp4 marketing_reel.mp4 automatizacion_reel.mp4 contenido_reel.mp4 agentes_reel.mp4 outro_cta.mp4 audio/ cultiva_bgm.mp3 output/ ← se crea automáticamente """
import bpy import os
──────────────────────────────────────────────
0. CONFIGURACIÓN DEL PROYECTO
──────────────────────────────────────────────
BASE_DIR = os.path.dirname(os.path.abspath(file)) RAW_DIR = os.path.join(BASE_DIR, "raw") AUDIO_DIR = os.path.join(BASE_DIR, "audio") OUTPUT_DIR = os.path.join(BASE_DIR, "output") os.makedirs(OUTPUT_DIR, exist_ok=True)
FPS = 24 CROSSFADE_FRAMES = 12 # 0.5 segundos de dissolve entre clips
Clips en orden de montaje
CLIPS = [ os.path.join(RAW_DIR, "intro_logo.mp4"), os.path.join(RAW_DIR, "marketing_reel.mp4"), os.path.join(RAW_DIR, "automatizacion_reel.mp4"), os.path.join(RAW_DIR, "contenido_reel.mp4"), os.path.join(RAW_DIR, "agentes_reel.mp4"), os.path.join(RAW_DIR, "outro_cta.mp4"), ]
Títulos superpuestos: (texto, inicio_seg, duración_seg)
TITLES = [ ("Marketing con IA", 5, 3), ("Automatización", 20, 3), ("Contenido Generativo", 35, 3), ("Agentes Inteligentes", 50, 3), ]
──────────────────────────────────────────────
1. INICIALIZAR ESCENA Y SECUENCIADOR
──────────────────────────────────────────────
scene = bpy.context.scene scene.render.fps = FPS
if not scene.sequence_editor: scene.sequence_editor_create()
sequences = scene.sequence_editor.sequences
Limpiar timeline si hubiera algo previo
for s in list(sequences): sequences.remove(s)
print("[CULTIVA] Timeline limpio. Comenzando montaje...")
──────────────────────────────────────────────
2. ENSAMBLAR CLIPS CON CROSS DISSOLVE
──────────────────────────────────────────────
current_frame = 1 prev_strip = None video_strips = []
for i, clip_path in enumerate(CLIPS): channel = 1 + (i % 2) # Alternamos canal 1 y 2 para los dissolves
# Si hay dissolve, retrocedemos el cursor CROSSFADE_FRAMES
if prev_strip and CROSSFADE_FRAMES > 0:
current_frame -= CROSSFADE_FRAMES
strip = sequences.new_movie(
name=os.path.splitext(os.path.basename(clip_path))[0],
filepath=clip_path,
channel=channel,
frame_start=current_frame,
)
# Cross dissolve entre clip anterior y este
if prev_strip and CROSSFADE_FRAMES > 0:
fade_start = current_frame
fade_end = current_frame + CROSSFADE_FRAMES
sequences.new_effect(
name=f"Fade_{i}",
type="GAMMA_CROSS",
channel=3,
frame_start=fade_start,
frame_end=fade_end,
seq1=prev_strip,
seq2=strip,
)
video_strips.append(strip)
current_frame += strip.frame_final_duration
prev_strip = strip
print(f"[CULTIVA] {len(video_strips)} clips ensamblados. Frame final: {current_frame}")
──────────────────────────────────────────────
3. CORRECCIÓN DE COLOR EN CLIPS DE CONTENIDO
(marketing, automatizacion, contenido, agentes)
──────────────────────────────────────────────
CLIPS_PARA_CC = [ "marketing_reel", "automatizacion_reel", "contenido_reel", "agentes_reel", ]
for strip in video_strips: if any(name in strip.name for name in CLIPS_PARA_CC): bc = strip.modifiers.new(name="BrightContrast", type="BRIGHT_CONTRAST") bc.bright = 0.1 bc.contrast = 0.15
cb = strip.modifiers.new(name="ColorBalance", type="COLOR_BALANCE")
# Ligero toque cálido en las luces (gain) y frío en las sombras (lift)
cb.color_balance.lift = (0.95, 0.95, 1.00)
cb.color_balance.gain = (1.10, 1.05, 0.95)
print(f"[CULTIVA] Color correction aplicada a: {strip.name}")
──────────────────────────────────────────────
4. MÚSICA DE FONDO CON FADE IN / FADE OUT
──────────────────────────────────────────────
MUSIC_PATH = os.path.join(AUDIO_DIR, "cultiva_bgm.mp3") FADE_IN_FRAMES = 1 * FPS # 1 segundo FADE_OUT_FRAMES = 3 * FPS # 3 segundos
audio = sequences.new_sound( name="CultivaIA_BGM", filepath=MUSIC_PATH, channel=6, frame_start=1, )
audio_end = audio.frame_final_end
Keyframes de volumen para fade in/out
audio.volume = 0.0 audio.keyframe_insert(data_path="volume", frame=1)
audio.volume = 0.65 audio.keyframe_insert(data_path="volume", frame=FADE_IN_FRAMES)
audio.volume = 0.65 audio.keyframe_insert(data_path="volume", frame=audio_end - FADE_OUT_FRAMES)
audio.volume = 0.0 audio.keyframe_insert(data_path="volume", frame=audio_end)
print(f"[CULTIVA] Música añadida con fade in ({FADE_IN_FRAMES}f) y fade out ({FADE_OUT_FRAMES}f).")
──────────────────────────────────────────────
5. TÍTULOS SUPERPUESTOS
──────────────────────────────────────────────
TITLE_CHANNEL = 5
for text_content, start_sec, dur_sec in TITLES: start_frame = int(start_sec * FPS) + 1 end_frame = start_frame + int(dur_sec * FPS)
text_strip = sequences.new_effect(
name=text_content[:20],
type="TEXT",
channel=TITLE_CHANNEL,
frame_start=start_frame,
frame_end=end_frame,
)
text_strip.text = text_content
text_strip.font_size = 70
text_strip.color = (1.0, 1.0, 1.0, 1.0) # Blanco opaco
text_strip.location = (0.5, 0.12) # Centrado inferior
text_strip.align_x = "CENTER"
text_strip.align_y = "CENTER"
text_strip.use_shadow = True
text_strip.shadow_color = (0.0, 0.0, 0.0, 0.8)
print(f"[CULTIVA] Título '{text_content}' en frame {start_frame}–{end_frame}")
──────────────────────────────────────────────
6. AJUSTAR RANGO DE RENDER
──────────────────────────────────────────────
all_strips = scene.sequence_editor.sequences_all frame_start = min(s.frame_final_start for s in all_strips) frame_end = max(s.frame_final_end for s in all_strips)
scene.frame_start = frame_start scene.frame_end = frame_end
print(f"[CULTIVA] Rango de render: frame {frame_start} → {frame_end} ({(frame_end-frame_start)/FPS:.1f} seg)")
──────────────────────────────────────────────
7. CONFIGURAR RENDER Y EXPORTAR
──────────────────────────────────────────────
output_path = os.path.join(OUTPUT_DIR, "cultiva_agency_reel_2026.mp4")
render = scene.render render.resolution_x = 1920 render.resolution_y = 1080 render.resolution_percentage = 100 render.filepath = output_path render.image_settings.file_format = "FFMPEG" render.ffmpeg.format = "MPEG4" render.ffmpeg.codec = "H264" render.ffmpeg.constant_rate_factor = "MEDIUM" # calidad equilibrada render.ffmpeg.audio_codec = "AAC" render.ffmpeg.audio_bitrate = 192
print(f"[CULTIVA] Iniciando render → {output_path}") bpy.ops.render.render(animation=True) print("[CULTIVA] ¡Render completado! Agency Reel 2026 listo.")
// qué_hace
Genera pipelines de edición de vídeo headless en Blender VSE con Python.
// cómo_lo_hace
Usa la API bpy para crear y orquestar strips de vídeo, audio e imagen, aplicar efectos y renderizar en segundo plano desde la línea de comandos.
// ejemplo_de_uso
Cuando necesitas automatizar una edición de vídeo repetitiva sin abrir la interfaz gráfica de Blender. Ej.: generar automáticamente un vídeo de resumen semanal concatenando clips y añadiendo música de fondo sin intervención manual.
// plataformas
// opiniones_de_la_comunidad
Opiniones
Cargando opiniones…
// pase_cultiva_ia
Llévate todo el arsenal con el Pase
Todas las skills, prompts y automatizaciones del catálogo en un único archivo, listas para usar: un pago, acceso de por vida y las novedades que añadamos. Sin suscripción.
Pago único · IVA incluido · pago seguro con Stripe.
Acceso inmediato · si no es lo que esperabas, te devolvemos los 10 €.