← Volver al catálogo
VídeoAutomatizaciónAvanzadoGratis

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.

Descargar SKILL.md

Descarga abierta · sin registro · para Blender, Python, FFmpeg

// resultado_de_ejemplo

""" 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

BlenderPythonFFmpegLinuxmacOSWindows
Categoría
Vídeo
Tipo
Automatización
Nivel
Avanzado
Licencia
Apache-2.0
Seguridad
seguro · riesgo bajo
Versión
1.0.0

// 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 €.