Mix

Blender

These are python tools for GUI base video editing automation using the blender MCP.

Tool Description

# GUI Video editor tools

These are python tools for GUI base video editing automation using the blender MCP.

## Instructions

- You MUST prefer the provided high-level tools instead of directly using bpy.
- Use bpy directly only if the high-level tools cannot accomplish your task.
- Use these tools ONLY with `execute_blender_code` - these are Blender-specific Python function
- Blender has a "Video Editing" workspace, even though it may not be listed when you check with bpy
- You MUST run the final python script within blender's execution environment as a SINGLE code block. Don't create separate files or split into multiple execution calls - each `execute_blender_code` call is stateless and variables/imports don't persist between calls.
- You MUST use absolute file paths when working, since Blender's working directory may not match your project directory.
- ALL functions are exposed through `blender` - NEVER import from submodules:
    Positive example

    <python_example>
    import sys, json
    tools_path = filepath.Join($<launchdir>, "go_backend", "tools")
    sys.path.insert(0, tools_path)
    from blender import (
        get_timeline_items
    )
    </python_example>

## ⚠️ Sequencer Rules

- No overlapping video/audio/image clips  - ALWAYS use a different channel for each one.
  - each one starts where previous ends
  - Calculate frame positions: `next_start = previous_start + previous_duration`
  - Example: Video1 ch1 (1-100), Video2 ch2 (101-200), Video3 ch1 (201-300) ✓

Common Patterns:

<python_example>

## Sequential: clips play one after another

add_video('clip1.mp4', 1, 1)      # frames 1-120
add_video('clip2.mp4', 1, 121)    # frames 121-240  
add_video('clip3.mp4', 1, 241)    # frames 241-360

## Layered: clips play simultaneously

add_video('background.mp4', 1, 1)  # base layer
add_video('overlay.mp4', 2, 50)    # on top, starts at frame 50
add_text('Title', 3, 100, 60)      # text overlay
</python_example>

## Quick Start Workflow

<python_example>

## Check available workspaces and switch to Video Editing

current = get_current_workspace()
print(f"Current workspace: {current}")

## Set timeline frame range

set_frame_range(1, 300)
frame_info = get_frame_range()
print(f"Timeline: {frame_info['frame_start']}-{frame_info['frame_end']}")

## Add background color and media to timeline

add_color((0.1, 0.1, 0.1, 1.0), 1, 0, 300)
add_video('/path/to/video.mp4', 2, 10)
add_text('Hello World', 3, 50, 120, font_size=72)

## Add transition between sequences

add_transition('video1', 'video2', 'CROSS', 15)

## Cut a video sequence at frame 100 (creates two separate sequences)

blade_cut('my_video', 100, 'video_part1', 'video_part2')

## Set playhead position and export

set_current_frame(150)
export_video('/path/to/output.mp4', resolution=(1920, 1080), fps=24)

## Capture preview screenshot at current frame

capture_preview_frame('/path/to/preview.png', resolution=(1920, 1080))

## Capture specific frame as JPEG

capture_preview_frame('/path/to/frame_100.jpg', frame=100, format='JPEG', quality=85)
</python_example>

### get_current_workspace()

Returns the name of the currently active Blender workspace

Returns:

- `str` - The workspace name (e.g., "Video Editing", "Modeling")

### get_timeline_items(channel=None)

Returns timeline sequences, optionally filtered by channel

Parameters:

- `channel` (Optional[int]) - Channel number to filter by, None for all sequences

Returns:

- `List[Dict[str, Any]]` - List of sequence dictionaries with name, type, channel, frame_start, frame_end, duration, filepath, original_resolution, transform, is_resized

### delete_timeline_item((sequence_name)

Delete a sequence from the timeline by name

Parameters:

- `sequence_name` (str) - Name of the sequence to delete

Returns:

- `Dict[str, Any]` - Dictionary with success status, message, and deleted sequence info

### blade_cut(sequence_name, cut_frame, left_name=None, right_name=None)

Cut a video or audio sequence at a specific frame, creating two separate sequences

Parameters:

- `sequence_name` (str) - Name of the sequence to cut (must be MOVIE or SOUND type)
- `cut_frame` (int) - Frame position where to make the cut
- `left_name` (Optional[str]) - Name for the left part (auto-generated if None)
- `right_name` (Optional[str]) - Name for the right part (auto-generated if None)

Returns:

- `Dict[str, Any]` - Dictionary with success status, message, original sequence info, and info about both created sequences

Note: This is the equivalent of a "razor blade" or "blade" tool in video editors. The original sequence is removed and replaced with two new sequences. Only works with MOVIE (video) and SOUND (audio) sequences.

### get_sequence_resize_info(sequence_name)

Get detailed resize information for a specific sequence

Parameters:

- `sequence_name` (str) - Name of the sequence to check

Returns:

- `Dict[str, Any]` - Detailed resize information with original_resolution, current_scale, effective_resolution, resize_method, fit_method, transform

## Media Operations

### add_image(filepath, channel, frame_start, name=None, fit_method='ORIGINAL', frame_end=None, position=None, scale=None)

Add an image element to the timeline at specific channel and position

Parameters:

- `filepath` (str) - Path to image file
- `channel` (int) - Channel number
- `frame_start` (int) - Starting frame position
- `name` (Optional[str]) - Sequence name
- `fit_method` (str) - How to fit image ('ORIGINAL', 'FIT', 'FILL', 'STRETCH')
- `frame_end` (Optional[int]) - Ending frame position (images can be extended to any duration)
- `position` (Optional[Tuple[float, float]]) - (x, y) offset in pixels from center
- `scale` (Optional[float]) - Uniform scale factor (1.0 = original size)

Returns:

- `Dict[str, Any]` - Sequence info dictionary matching get_timeline_items() format

Supported formats: .jpg, .jpeg, .png, .tiff, .tif, .exr, .hdr, .bmp, .tga

### add_video(filepath, channel, frame_start, name=None, fit_method='ORIGINAL', frame_end=None)

Add a video element to the timeline at specific channel and position

Parameters:

- `filepath` (str) - Path to video file
- `channel` (int) - Channel number
- `frame_start` (int) - Starting frame position
- `name` (Optional[str]) - Sequence name
- `fit_method` (str) - How to fit video ('ORIGINAL', 'FIT', 'FILL', 'STRETCH')
- `frame_end` (Optional[int]) - Ending frame position (videos can only be trimmed, not extended)

Returns:

- `Dict[str, Any]` - Sequence info dictionary matching get_timeline_items() format

Supported formats: .mp4, .mov, .avi, .mkv, .webm, .wmv, .m4v, .flv

### add_audio(filepath, channel, frame_start, name=None, frame_end=None)

Add an audio element to the timeline at specific channel and position

Parameters:

- `filepath` (str) - Path to audio file
- `channel` (int) - Channel number
- `frame_start` (int) - Starting frame position
- `name` (Optional[str]) - Sequence name
- `frame_end` (Optional[int]) - Ending frame position (audio can only be trimmed, not extended)

Returns:

- `Dict[str, Any]` - Sequence info dictionary matching get_timeline_items() format

Supported formats: .wav, .mp3, .flac, .ogg, .aac, .m4a, .wma

### add_text(text, channel, frame_start, duration, name=None, font_size=50, color=(1.0, 1.0, 1.0, 1.0), location=(0, 0), use_background=False, background_color=(0.0, 0.0, 0.0, 0.8))

Add a text element to the timeline at specific channel and position

Parameters:

- `text` (str) - The text content to display
- `channel` (int) - Channel number
- `frame_start` (int) - Starting frame position
- `duration` (int) - Duration in frames
- `name` (Optional[str]) - Sequence name
- `font_size` (int) - Font size in pixels
- `color` (Tuple[float, float, float, float]) - Text color as RGBA tuple
- `location` (Tuple[int, int]) - Text position as (X, Y) tuple
- `use_background` (bool) - Whether to show background behind text
- `background_color` (Tuple[float, float, float, float]) - Background color as RGBA tuple

Returns:

- `Dict[str, Any]` - Text sequence info dictionary matching get_timeline_items() format

### add_color(color, channel, frame_start, duration, name=None)

Add a solid color element to the timeline at specific channel and position. DO NOT use it to add images.

Parameters:

- `color` (Tuple[float, float, float, float]) - Color as RGBA tuple (values 0.0-1.0)
- `channel` (int) - Channel number
- `frame_start` (int) - Starting frame position
- `duration` (int) - Duration in frames
- `name` (Optional[str]) - Sequence name

Returns:

- `Dict[str, Any]` - Color sequence info dictionary matching get_timeline_items() format

### add_transition(sequence1_name, sequence2_name, transition_type='CROSS', duration=10, channel=None)

Add a transition effect between two sequences on the timeline

Parameters:

- `sequence1_name` (str) - Name of the first sequence
- `sequence2_name` (str) - Name of the second sequence
- `transition_type` (str) - Type of transition ('CROSS', 'WIPE', 'GAMMA_CROSS')
- `duration` (int) - Duration of transition in frames
- `channel` (Optional[int]) - Channel for transition effect

Returns:

- `Dict[str, Any]` - Transition info dictionary matching get_timeline_items() format

## Frame Range Operations

### set_frame_range(start_frame, end_frame)

Set the timeline frame range (start and end frames)

Parameters:

- `start_frame` (int) - Starting frame number for the timeline
- `end_frame` (int) - Ending frame number for the timeline

Returns:

- `Dict[str, Any]` - Dictionary with success, message, frame_start, frame_end

### get_frame_range()

Get the current timeline frame range and playhead position

Returns:

- `Dict[str, Any]` - Dictionary with frame_start, frame_end, frame_current, total_frames

### set_current_frame(frame)

Set the current playhead position on the timeline

Parameters:

- `frame` (int) - Frame number to set as current position

Returns:

- `Dict[str, Any]` - Dictionary with success, message, frame_current, in_range

### get_current_frame()

Get the current playhead position on the timeline

Returns:

- `int` - Current frame number

### modify_image(sequence_name, trim_start=None, trim_end=None, scale=None, position=None, rotation=None)

Modify image sequences on the timeline (trim, zoom, reposition)

Parameters:

- `sequence_name` (str) - Name of the sequence to modify
- `trim_start` (Optional[int]) - New start frame for trimming
- `trim_end` (Optional[int]) - New end frame for trimming
- `scale` (Optional[Union[float, Tuple[float, float]]]) - Scale factor - float for uniform or (x, y) tuple for non-uniform
- `position` (Optional[Tuple[float, float]]) - (x, y) offset in pixels from center
- `rotation` (Optional[float]) - Rotation angle in radians

Returns:

- `Dict[str, Any]` - Updated sequence info dictionary matching get_timeline_items() format

Note: Only works with IMAGE sequence types. Images can be extended beyond their original duration.

### modify_video(sequence_name, trim_start=None, trim_end=None, scale=None, position=None, rotation=None, speed=None)

Modify video sequences on the timeline (trim, zoom, reposition, speed)

Parameters:

- `sequence_name` (str) - Name of the sequence to modify
- `trim_start` (Optional[int]) - New start frame for trimming
- `trim_end` (Optional[int]) - New end frame for trimming
- `scale` (Optional[Union[float, Tuple[float, float]]]) - Scale factor - float for uniform or (x, y) tuple for non-uniform
- `position` (Optional[Tuple[float, float]]) - (x, y) offset in pixels from center
- `rotation` (Optional[float]) - Rotation angle in radians
- `speed` (Optional[float]) - Playback speed multiplier (0.1-10.0, where 1.0 = normal speed)

Returns:

- `Dict[str, Any]` - Updated sequence info dictionary matching get_timeline_items() format

Note: Only works with MOVIE sequence types. Videos can only be trimmed, not extended beyond their original duration. Speed control affects playback rate and effective duration.

### modify_audio(sequence_name, trim_start=None, trim_end=None, volume=None, pan=None)

Modify audio sequences on the timeline (trim, volume, pan)

Parameters:

- `sequence_name` (str) - Name of the sequence to modify
- `trim_start` (Optional[int]) - New start frame for trimming
- `trim_end` (Optional[int]) - New end frame for trimming
- `volume` (Optional[float]) - Volume level (0.0-100.0, where 100.0 is full volume)
- `pan` (Optional[float]) - Stereo panning (-inf to +inf, 0.0 is center, only for mono sources)

Returns:

- `Dict[str, Any]` - Updated sequence info dictionary matching get_timeline_items() format

Note: Only works with SOUND sequence types. Other types (IMAGE, MOVIE, TEXT, COLOR, effects) will raise an error.

### detach_audio_from_video(video_sequence_name, audio_channel, audio_name=None)

Detach audio from a video sequence and create a separate audio sequence

Parameters:

- `video_sequence_name` (str) - Name of the video sequence to detach audio from
- `audio_channel` (int) - Channel number to place the detached audio sequence
- `audio_name` (Optional[str]) - Name for the audio sequence (auto-generated if None)

Returns:

- `Dict[str, Any]` - Dictionary containing:
  - `success` (bool) - Whether the operation succeeded
  - `message` (str) - Success/error message  
  - `video_sequence` (Dict[str, Any]) - Original video sequence info
  - `audio_sequence` (Optional[Dict[str, Any]]) - Created audio sequence info (None if no audio)

Note: Only works with MOVIE sequence types. Creates a new SOUND sequence from the video's audio track. If the video has no audio, returns success=False with appropriate message.

## Timeline Operations

### export_video(output_path, frame_start=None, frame_end=None, resolution=(1920, 1080), fps=24, video_format='MPEG4', codec='H264', quality='HIGH')

Export timeline sequences to a video file

Parameters:

- `output_path` (str) - Path for the output video file
- `frame_start` (Optional[int]) - Starting frame (auto-detected if None)
- `frame_end` (Optional[int]) - Ending frame (auto-detected if None)
- `resolution` (Tuple[int, int]) - Video resolution as (width, height) tuple
- `fps` (int) - Frames per second
- `video_format` (str) - Video container format ('MPEG4', 'AVI', 'QUICKTIME', 'WEBM')
- `codec` (str) - Video codec ('H264', 'XVID', 'THEORA', 'VP9')
- `quality` (str) - Quality preset ('LOW', 'MEDIUM', 'HIGH', 'LOSSLESS')

Returns:

- `Dict[str, Any]` - Export info with output_path, frame_start, frame_end, duration, resolution, fps, file_size, success

### capture_preview_frame(output_path, frame=None, resolution=(1920, 1080), format='PNG', quality=90)

Capture a screenshot of the current preview in the video editor

Parameters:

- `output_path` (str) - Path for the output image file
- `frame` (Optional[int]) - Frame number to capture (uses current frame if None)
- `resolution` (Tuple[int, int]) - Image resolution as (width, height) tuple
- `format` (str) - Image format ('PNG', 'JPEG', 'TIFF', 'BMP', 'TARGA')
- `quality` (int) - Image quality for JPEG format (1-100)

Returns:

- `Dict[str, Any]` - Capture info with output_path, frame, resolution, format, file_size, success

Supported formats: PNG (default), JPEG, TIFF, BMP, TARGA

## Video Resize Detection

To detect if a video has been resized after loading in Blender:

<python_example>

# Check all sequences for resizing

sequences = get_timeline_items()
resized_sequences = [seq for seq in sequences if seq['is_resized']]

# Get detailed info for a specific sequence

resize_info = get_sequence_resize_info('my_video')
if resize_info['is_resized']:
    print(f"Video scaled from {resize_info['original_resolution']} to {resize_info['effective_resolution']}")
</python_example>

On this page