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.🎨 Color Backgrounds
Replace background with solid colors using hex codes
✨ Transparent Videos
Create videos with transparency for custom overlays
Quick Navigation
🎨 Color Backgrounds
🎨 Color Backgrounds
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: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)
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}')
# 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"
}
}'
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 sizesDecoder Required: WebM VP9 transparency requires
libvpx-vp9 decoder. Works most of the time, but not guaranteed on all systems.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)
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}')
# 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"
}
}'
Using WebM Videos in Your Projects
# 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!
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()
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();
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.MOV ProRes (Professional)
Best for: Professional video editing (Final Cut Pro, Premiere Pro)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)
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}')
# 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"
}
}'
Using MOV Videos
# 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
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()
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();
PNG Sequence
Best for: GIF creation, frame-by-frame editing, maximum qualityimport { 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)
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}')
# 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"
}
}'
Using PNG Sequences
# 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
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()
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();
Pro Bundle (Professional Workflow)
Best for: Unscreen workflows, ZIP handling, maximum flexibilityimport { 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)
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}')
# 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"
}
}'
Pro Bundle Contents
The Pro Bundle ZIP contains:color.mp4- Normalized foreground videoalpha.mp4- 8-bit grayscale matteaudio.m4a- Audio track (if present)manifest.json- Technical specifications
Using Pro Bundle
# 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
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()
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();
Stacked Video (Universal Format)
Best for: Universal compatibility, single file handling (top: video, bottom: mask)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)
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}')
# 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"
}
}'
Stacked Video Structure
- Top Half: Original video (1080x1080)
- Bottom Half: Grayscale mask (1080x1080)
- Total Dimensions: 1080x2160 (2:1 aspect ratio)
Using Stacked Videos
# 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
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()
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();
Testing Your Setup
Before processing videos, test your FFmpeg installation:For detailed positioning and scaling techniques, see the Positioning Guide in the Video Composition section.
# Check if libvpx-vp9 decoder is available
ffmpeg -decoders | grep libvpx-vp9
# Should output:
# V..... libvpx-vp9 libvpx VP9 (codec vp9)
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()
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();
