> ## Documentation Index
> Fetch the complete documentation index at: https://docs.videobgremover.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transparent Video Formats | WebM VP9, MOV ProRes

> Complete guide to transparent video formats. Learn about WebM VP9, MOV ProRes, PNG sequences, and Pro Bundle formats for video background removal.

## Overview

The VideoBGRemover API offers multiple background options for different use cases. This guide covers the technical details of each format and how to use them in your projects.

For complete workflows and implementation examples, see the [Background Removal Guide](/video-background-removal/guide).

<CardGroup cols={2}>
  <Card title="🎨 Color Backgrounds" icon="palette">
    Replace background with solid colors using hex codes
  </Card>

  <Card title="✨ Transparent Videos" icon="sparkles">
    Create videos with transparency for custom overlays
  </Card>
</CardGroup>

***

## Quick Navigation

<AccordionGroup>
  <Accordion title="🎨 Color Backgrounds" icon="palette">
    * [Simple Colors](#simple-color-replacement)
    * [Popular Colors](#popular-colors)
    * [Custom Hex Codes](#custom-hex-codes)
  </Accordion>

  <Accordion title="✨ Transparent Formats" icon="sparkles">
    * [WebM VP9 (Recommended)](#webm-vp9-recommended)
    * [MOV ProRes (Professional)](#mov-prores-professional)
    * [PNG Sequence (Frame-by-Frame)](#png-sequence)
    * [Pro Bundle (Advanced)](#pro-bundle-professional-workflow)
    * [Stacked Video (Analysis)](#stacked-video-analysis-format)
  </Accordion>
</AccordionGroup>

## Color Backgrounds

Perfect for simple background replacement with solid colors. No additional processing needed - just specify a hex color code.

### Simple Color Replacement

Replace the background with any solid color using hex codes:

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Start job with red background directly
  const finalStatus = await video.removeBackground({ client, options: {
    background: { type: 'color', color: '#FF0000' }
  }})
  console.log('Red background video URL:', finalStatus.processed_video_url)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Start job with red background directly
  final_status = video.remove_background(client, {
      'background': {'type': 'color', 'color': '#FF0000'}
  })
  print(f'Red background video URL: {final_status.processed_video_url}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with color background
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "color",
        "color": "#FF0000"
      }
    }'
  ```
</CodeGroup>

### Popular Colors

| Color     | Hex Code  | Use Case                 |
| --------- | --------- | ------------------------ |
| 🔴 Red    | `#FF0000` | Bold, attention-grabbing |
| 🟢 Green  | `#00FF00` | Chroma key standard      |
| 🔵 Blue   | `#0000FF` | Professional, clean      |
| ⚪ White   | `#FFFFFF` | Clean, minimal           |
| ⚫ Black   | `#000000` | Dramatic, cinematic      |
| 🎨 Custom | `#7C3AED` | Any hex code             |

***

## Transparent Formats

For advanced compositing, custom backgrounds, and professional workflows. These formats preserve transparency for maximum flexibility.

**What are transparent formats?** Video files that preserve the alpha channel (transparency) so you can overlay them on custom backgrounds. However, they can be tricky to use - WebM works in Chrome but not all browsers, MOV works in Safari but requires specific codecs.

When you need custom backgrounds or advanced compositing, use transparent formats:

### Format Comparison

| Format            | File Size     | Quality      | Use Case                                          | Compatibility        |
| ----------------- | ------------- | ------------ | ------------------------------------------------- | -------------------- |
| **WebM VP9**      | 🟢 Small      | 🟢 Excellent | Easy overlay, API usage                           | Requires VP9 decoder |
| **MOV ProRes**    | 🔴 Very Large | 🟢 Perfect   | Large files, professional editing                 | Video editors        |
| **PNG Sequence**  | 🔴 Very Large | 🟢 Perfect   | GIF creation, frame-by-frame                      | Universal            |
| **Pro Bundle**    | 🟡 Medium     | 🟢 Perfect   | Unscreen workflows, ZIP handling                  | Universal            |
| **Stacked Video** | 🟡 Medium     | 🟢 Perfect   | Universal, single file (top: video, bottom: mask) | Universal            |

## WebM VP9 (Recommended)

**Best for:** Easy overlay workflows, API usage, small file sizes

<Warning>
  **Decoder Required:** WebM VP9 transparency requires `libvpx-vp9` decoder. Works most of the time, but not guaranteed on all systems.
</Warning>

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video, RemoveBGOptions, Prefer } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Remove background with WebM VP9 format
  const options = new RemoveBGOptions(Prefer.WEBM_VP9)
  const transparent = await video.removeBackground({ client, options })

  console.log('Transparent WebM ready:', transparent.primaryPath)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video, RemoveBGOptions, Prefer
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Remove background with WebM VP9 format
  options = RemoveBGOptions(prefer=Prefer.WEBM_VP9)
  transparent = video.remove_background(client, options)

  print(f'Transparent WebM ready: {transparent.primary_path}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with WebM VP9 format
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "transparent",
        "transparent_format": "webm_vp9"
      }
    }'
  ```
</CodeGroup>

### Using WebM Videos in Your Projects

<CodeGroup>
  ```bash FFmpeg theme={"dark"}
      # Overlay WebM on custom background
      ffmpeg -i background.jpg -i transparent_video.webm \
        -c:v libvpx-vp9 \
        -filter_complex "[1:v]setpts=PTS-STARTPTS[video]; \
                         [0:v][video]overlay=x=(W-w)/2:y=(H-h)/2:shortest=1" \
        -c:v libx264 -c:a aac output.mp4

  # Important: Use -c:v libvpx-vp9 decoder to preserve alpha channels!
  ```

  ```python Python theme={"dark"}
      import ffmpeg

      # Load inputs
      background = ffmpeg.input('background.jpg', loop=1)
      video = ffmpeg.input('transparent_video.webm', **{'c:v': 'libvpx-vp9'})

      # Normalize timestamps and overlay
      video_norm = ffmpeg.filter(video, 'setpts', 'PTS-STARTPTS')
      output = ffmpeg.overlay(background, video_norm,
                             x='(W-w)/2', y='(H-h)/2', shortest=1)

      # Export
      ffmpeg.output(output, 'output.mp4',
                    vcodec='libx264', acodec='aac').run()
  ```

  ```typescript Node.js theme={"dark"}
  const ffmpeg = require('fluent-ffmpeg');

  // Load inputs
  const background = ffmpeg().input('background.jpg').loop();
  const video = ffmpeg().input('transparent_video.webm').inputOptions(['-c:v', 'libvpx-vp9']);

  // Create overlay
  background
    .complexFilter([
      {
        filter: 'setpts',
        inputs: '1:v',
        outputs: 'video_norm',
        options: 'PTS-STARTPTS'
      },
      {
        filter: 'overlay',
        inputs: ['0:v', 'video_norm'],
        outputs: 'output',
        options: `x=(W-w)/2:y=(H-h)/2:shortest=1`
      }
    ])
    .outputOptions(['-c:v', 'libx264', '-c:a', 'aac'])
    .output('output.mp4')
    .run();
  ```
</CodeGroup>

<Warning>
  **WebM Alpha Channel Issue:** The default VP9 decoder strips alpha channels. Always use `libvpx-vp9` decoder for proper transparency. If unavailable, use Stacked Video format instead.
</Warning>

## MOV ProRes (Professional)

**Best for:** Professional video editing (Final Cut Pro, Premiere Pro)

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video, RemoveBGOptions, Prefer } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Remove background with MOV ProRes format
  const options = new RemoveBGOptions(Prefer.MOV_PRORES)
  const transparent = await video.removeBackground({client, options})

  console.log('Transparent MOV ready:', transparent.primaryPath)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video, RemoveBGOptions, Prefer
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Remove background with MOV ProRes format
  options = RemoveBGOptions(prefer=Prefer.MOV_PRORES)
  transparent = video.remove_background(client, options)

  print(f'Transparent MOV ready: {transparent.primary_path}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with MOV ProRes format
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "transparent",
        "transparent_format": "mov_prores"
      }
    }'
  ```
</CodeGroup>

### Using MOV Videos

<CodeGroup>
  ```bash FFmpeg theme={"dark"}
      # Overlay MOV ProRes on background
      ffmpeg -i background.jpg -i transparent_video.mov \
        -filter_complex "[1:v]setpts=PTS-STARTPTS[video]; [0:v][video]overlay=x=100:y=200:shortest=1" \
        -c:v libx264 -c:a aac output.mp4
  ```

  ```python Python theme={"dark"}
      import ffmpeg

      background = ffmpeg.input('background.jpg', loop=1)
      video = ffmpeg.input('transparent_video.mov')

      # Position at specific coordinates
      video_norm = ffmpeg.filter(video, 'setpts', 'PTS-STARTPTS')
      output = ffmpeg.overlay(background, video_norm,
                             x=100, y=200, shortest=1)

      ffmpeg.output(output, 'output.mp4',
                    vcodec='libx264', acodec='aac').run()
  ```

  ```typescript Node.js theme={"dark"}
  const ffmpeg = require('fluent-ffmpeg');

  const background = ffmpeg().input('background.jpg').loop();
  const video = ffmpeg().input('transparent_video.mov');

  // Position at specific coordinates
  background
    .complexFilter([
      {
        filter: 'setpts',
        inputs: '1:v',
        outputs: 'video_norm',
        options: 'PTS-STARTPTS'
      },
      {
        filter: 'overlay',
        inputs: ['0:v', 'video_norm'],
        outputs: 'output',
        options: 'x=100:y=200:shortest=1'
      }
    ])
    .outputOptions(['-c:v', 'libx264', '-c:a', 'aac'])
    .output('output.mp4')
    .run();
  ```
</CodeGroup>

## PNG Sequence

**Best for:** GIF creation, frame-by-frame editing, maximum quality

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video, RemoveBGOptions, Prefer } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Remove background with PNG sequence format
  const options = new RemoveBGOptions(Prefer.PNG_SEQUENCE)
  const transparent = await video.removeBackground({client, options})

  console.log('PNG sequence ready:', transparent.primaryPath)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video, RemoveBGOptions, Prefer
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Remove background with PNG sequence format
  options = RemoveBGOptions(prefer=Prefer.PNG_SEQUENCE)
  transparent = video.remove_background(client, options)

  print(f'PNG sequence ready: {transparent.primary_path}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with PNG sequence format
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "transparent",
        "transparent_format": "png_sequence"
      }
    }'
  ```
</CodeGroup>

### Using PNG Sequences

<CodeGroup>
  ```bash FFmpeg theme={"dark"}
      # Extract ZIP and create video from PNG sequence
      unzip png_sequence.zip -d frames/

      # Overlay PNG sequence on background
      ffmpeg -loop 1 -i background.jpg \
             -framerate 24 -i frames/frame_%04d.png \
             -filter_complex "[1:v]setpts=PTS-STARTPTS[video]; \
                              [0:v][video]overlay=x=(W-w)/2:y=(H-h)/2:shortest=1" \
             -c:v libx264 -t 5 output.mp4
  ```

  ```python Python theme={"dark"}
      import ffmpeg
      import zipfile

      # Extract PNG sequence
      with zipfile.ZipFile('png_sequence.zip', 'r') as zip_ref:
          zip_ref.extractall('frames/')

      # Create video from sequence
      background = ffmpeg.input('background.jpg', loop=1)
      frames = ffmpeg.input('frames/frame_%04d.png', framerate=24)

      frames_norm = ffmpeg.filter(frames, 'setpts', 'PTS-STARTPTS')
      output = ffmpeg.overlay(background, frames_norm,
                             x='(W-w)/2', y='(H-h)/2', shortest=1)

      ffmpeg.output(output, 'output.mp4', t=5, vcodec='libx264').run()
  ```

  ```typescript Node.js theme={"dark"}
  const ffmpeg = require('fluent-ffmpeg');
  const fs = require('fs');
  const AdmZip = require('adm-zip');

  // Extract PNG sequence
  const zip = new AdmZip('png_sequence.zip');
  zip.extractAllTo('frames/', true);

  // Create video from sequence
  ffmpeg()
    .input('background.jpg')
    .loop()
    .input('frames/frame_%04d.png')
    .inputOptions(['-framerate', '24'])
    .complexFilter([
      {
        filter: 'setpts',
        inputs: '1:v',
        outputs: 'frames_norm',
        options: 'PTS-STARTPTS'
      },
      {
        filter: 'overlay',
        inputs: ['0:v', 'frames_norm'],
        outputs: 'output',
        options: `x=(W-w)/2:y=(H-h)/2:shortest=1`
      }
    ])
    .outputOptions(['-c:v', 'libx264', '-t', '5'])
    .output('output.mp4')
    .run();
  ```
</CodeGroup>

## Pro Bundle (Professional Workflow)

**Best for:** Unscreen workflows, ZIP handling, maximum flexibility

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video, RemoveBGOptions, Prefer } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Remove background with Pro Bundle format
  const options = new RemoveBGOptions(Prefer.PRO_BUNDLE)
  const transparent = await video.removeBackground({client, options})

  console.log('Pro Bundle ready:', transparent.primaryPath)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video, RemoveBGOptions, Prefer
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Remove background with Pro Bundle format
  options = RemoveBGOptions(prefer=Prefer.PRO_BUNDLE)
  transparent = video.remove_background(client, options)

  print(f'Pro Bundle ready: {transparent.primary_path}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with Pro Bundle format
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "transparent",
        "transparent_format": "pro_bundle"
      }
    }'
  ```
</CodeGroup>

### Pro Bundle Contents

The Pro Bundle ZIP contains:

* `color.mp4` - Normalized foreground video
* `alpha.mp4` - 8-bit grayscale matte
* `audio.m4a` - Audio track (if present)
* `manifest.json` - Technical specifications

### Using Pro Bundle

<CodeGroup>
  ```bash FFmpeg theme={"dark"}
      # Extract bundle
      unzip pro_bundle.zip -d bundle/

      # Combine color and alpha for transparency
      ffmpeg -i bundle/color.mp4 -i bundle/alpha.mp4 \
             -filter_complex "[0:v]format=rgba[color]; \
                              [1:v]format=gray[alpha]; \
                              [color][alpha]alphamerge[transparent]" \
             transparent_video.mov

      # Overlay on background
      ffmpeg -i background.jpg -i transparent_video.mov \
             -filter_complex "[1:v]setpts=PTS-STARTPTS[video]; \
                              [0:v][video]overlay=x=(W-w)/2:y=(H-h)/2:shortest=1" \
             -c:v libx264 -c:a aac final_output.mp4
  ```

  ```python Python theme={"dark"}
      import ffmpeg
      import zipfile

      # Extract bundle
      with zipfile.ZipFile('pro_bundle.zip', 'r') as zip_ref:
          zip_ref.extractall('bundle/')

      # Combine color and alpha
      color = ffmpeg.input('bundle/color.mp4')
      alpha = ffmpeg.input('bundle/alpha.mp4')

      color_rgba = ffmpeg.filter(color, 'format', 'rgba')
      alpha_gray = ffmpeg.filter(alpha, 'format', 'gray')
      transparent = ffmpeg.filter([color_rgba, alpha_gray], 'alphamerge')

      # Overlay on background
      background = ffmpeg.input('background.jpg', loop=1)
      transparent_norm = ffmpeg.filter(transparent, 'setpts', 'PTS-STARTPTS')

      output = ffmpeg.overlay(background, transparent_norm,
                             x='(W-w)/2', y='(H-h)/2', shortest=1)

      ffmpeg.output(output, 'final_output.mp4',
                    vcodec='libx264', acodec='aac').run()
  ```

  ```typescript Node.js theme={"dark"}
  const ffmpeg = require('fluent-ffmpeg');
  const AdmZip = require('adm-zip');

  // Extract bundle
  const zip = new AdmZip('pro_bundle.zip');
  zip.extractAllTo('bundle/', true);

  // Combine color and alpha for transparency
  ffmpeg()
    .input('bundle/color.mp4')
    .input('bundle/alpha.mp4')
    .complexFilter([
      { filter: 'format', inputs: '0:v', outputs: 'color', options: 'rgba' },
      { filter: 'format', inputs: '1:v', outputs: 'alpha', options: 'gray' },
      { filter: 'alphamerge', inputs: ['color', 'alpha'], outputs: 'transparent' }
    ])
    .output('transparent_video.mov')
    .on('end', () => {
      // Overlay on background
      ffmpeg()
        .input('background.jpg')
        .loop()
        .input('transparent_video.mov')
        .complexFilter([
          {
            filter: 'setpts',
            inputs: '1:v',
            outputs: 'video_norm',
            options: 'PTS-STARTPTS'
          },
          {
            filter: 'overlay',
            inputs: ['0:v', 'video_norm'],
            outputs: 'output',
            options: `x=(W-w)/2:y=(H-h)/2:shortest=1`
          }
        ])
        .outputOptions(['-c:v', 'libx264', '-c:a', 'aac'])
        .output('final_output.mp4')
        .run();
    })
    .run();
  ```
</CodeGroup>

## Stacked Video (Universal Format)

**Best for:** Universal compatibility, single file handling (top: video, bottom: mask)

<CodeGroup>
  ```typescript Node.js theme={"dark"}
  import { VideoBGRemoverClient, Video, RemoveBGOptions, Prefer } from '@videobgremover/sdk'

  const client = new VideoBGRemoverClient(process.env.VIDEOBGREMOVER_API_KEY!)
  const video = Video.open('https://example.com/video.mp4')

  // Remove background with Stacked Video format
  const options = new RemoveBGOptions(Prefer.STACKED_VIDEO)
  const transparent = await video.removeBackground({client, options})

  console.log('Stacked Video ready:', transparent.primaryPath)
  ```

  ```python Python theme={"dark"}
  from videobgremover import VideoBGRemoverClient, Video, RemoveBGOptions, Prefer
  import os

  client = VideoBGRemoverClient(os.getenv('VIDEOBGREMOVER_API_KEY'))
  video = Video.open('https://example.com/video.mp4')

  # Remove background with Stacked Video format
  options = RemoveBGOptions(prefer=Prefer.STACKED_VIDEO)
  transparent = video.remove_background(client, options)

  print(f'Stacked Video ready: {transparent.primary_path}')
  ```

  ```bash cURL theme={"dark"}
  # Start processing with Stacked Video format
  curl -X POST https://api.videobgremover.com/v1/jobs/$JOB_ID/start \
    -H "X-Api-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "background": {
        "type": "transparent",
        "transparent_format": "stacked_video"
      }
    }'
  ```
</CodeGroup>

### Stacked Video Structure

* **Top Half:** Original video (1080x1080)
* **Bottom Half:** Grayscale mask (1080x1080)
* **Total Dimensions:** 1080x2160 (2:1 aspect ratio)

### Using Stacked Videos

<CodeGroup>
  ```bash FFmpeg theme={"dark"}
      # Extract and apply mask in one command
      ffmpeg -i background.jpg -i stacked_video.mp4 \
        -filter_complex "
          [1:v]split=2[original][mask_source];
          [original]crop=1080:1080:0:0[top];
          [mask_source]crop=1080:1080:0:1080,format=gray,geq='if(gte(lum(X,Y),128),255,0)'[binary_mask];
          [top]format=rgba[top_rgba];
          [top_rgba][binary_mask]alphamerge[masked_video];
          [0:v][masked_video]overlay=x=(W-w)/2:y=(H-h)/2:shortest=1
        " \
        -c:v libx264 -c:a aac output.mp4
  ```

  ```python Python theme={"dark"}
      import ffmpeg

      background = ffmpeg.input('background.jpg', loop=1)
      stacked = ffmpeg.input('stacked_video.mp4')

      # Extract top half (original video)
      top = ffmpeg.filter(stacked, 'crop', 1080, 1080, 0, 0)
      top_rgba = ffmpeg.filter(top, 'format', 'rgba')

      # Extract bottom half (mask) and make binary
      mask = ffmpeg.filter(stacked, 'crop', 1080, 1080, 0, 1080)
      mask_gray = ffmpeg.filter(mask, 'format', 'gray')
      binary_mask = ffmpeg.filter(mask_gray, 'geq',
                                  "if(gte(lum(X,Y),128),255,0)")

      # Apply mask and overlay
      masked_video = ffmpeg.filter([top_rgba, binary_mask], 'alphamerge')
      masked_norm = ffmpeg.filter(masked_video, 'setpts', 'PTS-STARTPTS')

      output = ffmpeg.overlay(background, masked_norm,
                             x='(W-w)/2', y='(H-h)/2', shortest=1)

      ffmpeg.output(output, 'output.mp4',
                    vcodec='libx264', acodec='aac').run()
  ```

  ```typescript Node.js theme={"dark"}
  const ffmpeg = require('fluent-ffmpeg');

  const background = ffmpeg().input('background.jpg').loop();
  const stacked = ffmpeg().input('stacked_video.mp4');

  // Extract and apply mask in one command
  background
    .complexFilter([
      { filter: 'split', inputs: '1:v', outputs: ['original', 'mask_source'] },
      { filter: 'crop', inputs: 'original', outputs: 'top', options: '1080:1080:0:0' },
      { filter: 'crop', inputs: 'mask_source', outputs: 'mask', options: '1080:1080:0:1080' },
      { filter: 'format', inputs: 'mask', outputs: 'mask_gray', options: 'gray' },
      {
        filter: 'geq',
        inputs: 'mask_gray',
        outputs: 'binary_mask',
        options: "if(gte(lum(X,Y),128),255,0)"
      },
      { filter: 'format', inputs: 'top', outputs: 'top_rgba', options: 'rgba' },
      { filter: 'alphamerge', inputs: ['top_rgba', 'binary_mask'], outputs: 'masked_video' },
      {
        filter: 'setpts',
        inputs: 'masked_video',
        outputs: 'masked_norm',
        options: 'PTS-STARTPTS'
      },
      {
        filter: 'overlay',
        inputs: ['0:v', 'masked_norm'],
        outputs: 'output',
        options: `x=(W-w)/2:y=(H-h)/2:shortest=1`
      }
    ])
    .outputOptions(['-c:v', 'libx264', '-c:a', 'aac'])
    .output('output.mp4')
    .run();
  ```
</CodeGroup>

## Testing Your Setup

Before processing videos, test your FFmpeg installation:

<Note>
  For detailed positioning and scaling techniques, see the [Positioning Guide](/video-composition/positioning) in the Video Composition section.
</Note>

<CodeGroup>
  ```bash Test WebM Support theme={"dark"}
      # Check if libvpx-vp9 decoder is available
      ffmpeg -decoders | grep libvpx-vp9

      # Should output:
      # V..... libvpx-vp9           libvpx VP9 (codec vp9)
  ```

  ```python Python Test theme={"dark"}
      import subprocess

      def test_webm_support():
          try:
              result = subprocess.run(['ffmpeg', '-decoders'],
                                    capture_output=True, text=True)
              if 'libvpx-vp9' in result.stdout:
                  print("✅ WebM alpha channels supported")
                  return True
              else:
                  print("❌ Use stacked video format instead")
                  return False
          except:
              print("❌ FFmpeg not found")
              return False

      test_webm_support()
  ```

  ```typescript Node.js Test theme={"dark"}
  const { exec } = require('child_process');

  function testWebmSupport() {
    exec('ffmpeg -decoders', (error, stdout, stderr) => {
      if (error) {
        console.log('❌ FFmpeg not found');
        return false;
      }

      if (stdout.includes('libvpx-vp9')) {
        console.log('✅ WebM alpha channels supported');
        return true;
      } else {
        console.log('❌ Use stacked video format instead');
        return false;
      }
    });
  }

  testWebmSupport();
  ```
</CodeGroup>
