Video Overlays
Add picture-in-picture, B-roll, and video element overlays to your videos
Video overlay elements allow you to composite additional videos on top of your base video. Perfect for picture-in-picture (PiP), webcam overlays, B-roll footage, reaction videos, and multi-video compositions.
Video Overlay Element Structure
interface VideoOverlayElement {
type: 'video';
url: string;
timing: TimingConfig;
position: PositionConfig;
size: SizeConfig;
effects?: VisualEffects;
zIndex?: number;
loop?: boolean;
}Required Properties
| Property | Type | Description |
|---|---|---|
type | 'video' | Must be "video" |
url | string | URL to the video file (must be publicly accessible) |
timing | TimingConfig | When to show the video overlay |
position | PositionConfig | Where to place the video |
size | SizeConfig | Size of the video overlay |
Optional Properties
| Property | Type | Default | Description |
|---|---|---|---|
effects | VisualEffects | undefined | Visual effects like opacity and fades |
zIndex | number | 0 | Stacking order (higher = on top) |
loop | boolean | false | Whether to loop the video overlay |
Video Overlays vs Base Video: Video overlays are composited on top of your base video. They work like image and GIF overlays but with video content.
Supported Formats
Video overlays support the following formats:
- MP4 - H.264 codec (recommended for best compatibility)
- WebM - VP8/VP9 codec
- MOV - QuickTime format
- AVI - Audio Video Interleave
Format Recommendation: Use MP4 with H.264 codec for best compatibility and performance.
Audio Handling
Important: Video overlay audio is disabled by default. Video overlays are rendered without audio to prevent audio conflicts. Only the base video's audio (and audio elements) are included in the final output.
If you need audio from an overlay video, use an Audio Element instead and sync the timing.
Loop Property
The loop property controls whether the video overlay repeats:
Loop Disabled (Default)
The video plays once and stops:
{
"type": "video",
"url": "https://example.com/overlay.mp4",
"loop": false
}Use cases:
- One-time B-roll footage
- Single playthrough effects
- Timed video inserts
Loop Enabled
The video continuously loops while visible:
{
"type": "video",
"url": "https://example.com/background-loop.mp4",
"loop": true
}Use cases:
- Background video effects
- Repeating patterns
- Continuous animations
- Short loops as decorative elements
Timing vs Loop: If your timing duration is longer than the video overlay
duration and loop is false, the overlay will freeze on the last frame. Set
loop: true to repeat the video.
Complete Examples
Picture-in-Picture Webcam
Add a webcam overlay in the corner:
curl -X POST https://api.videocascade.com/v1/videos \
-H "Authorization: Bearer vca_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"fileUrl": "https://example.com/screen-recording.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/webcam.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "bottom-right" },
"size": {
"width": "25%",
"fit": "cover"
},
"effects": {
"fadeIn": { "duration": 0.5 },
"fadeOut": { "duration": 0.5 }
},
"zIndex": 10
}
]
}'const response = await fetch('https://api.videocascade.com/v1/videos', {
method: 'POST',
headers: {
'Authorization': 'Bearer vca_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
fileUrl: 'https://example.com/screen-recording.mp4',
elements: [
{
type: 'video',
url: 'https://example.com/webcam.mp4',
timing: { entireVideo: true },
position: { anchor: 'bottom-right' },
size: {
width: '25%',
fit: 'cover',
},
effects: {
fadeIn: { duration: 0.5 },
fadeOut: { duration: 0.5 },
},
zIndex: 10,
},
],
}),
});
const data = await response.json();
console.log('Video ID:', data.videoId);import requests
response = requests.post(
'https://api.videocascade.com/v1/videos',
headers={
'Authorization': 'Bearer vca_your_api_key',
'Content-Type': 'application/json',
},
json={
'fileUrl': 'https://example.com/screen-recording.mp4',
'elements': [
{
'type': 'video',
'url': 'https://example.com/webcam.mp4',
'timing': {'entireVideo': True},
'position': {'anchor': 'bottom-right'},
'size': {
'width': '25%',
'fit': 'cover',
},
'effects': {
'fadeIn': {'duration': 0.5},
'fadeOut': {'duration': 0.5},
},
'zIndex': 10,
},
],
}
)
data = response.json()
print(f"Video ID: {data['videoId']}")interface VideoOverlayElement {
type: 'video';
url: string;
timing: { entireVideo: boolean };
position: { anchor: string };
size: {
width: string;
fit: string;
};
effects?: {
fadeIn?: { duration: number };
fadeOut?: { duration: number };
};
zIndex: number;
}
const pipOverlay: VideoOverlayElement = {
type: 'video',
url: 'https://example.com/webcam.mp4',
timing: { entireVideo: true },
position: { anchor: 'bottom-right' },
size: {
width: '25%',
fit: 'cover',
},
effects: {
fadeIn: { duration: 0.5 },
fadeOut: { duration: 0.5 },
},
zIndex: 10,
};
const response = await fetch('https://api.videocascade.com/v1/videos', {
method: 'POST',
headers: {
'Authorization': 'Bearer vca_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
fileUrl: 'https://example.com/screen-recording.mp4',
elements: [pipOverlay],
}),
});B-Roll Insert
Insert B-roll footage at a specific time:
{
"fileUrl": "https://example.com/main-video.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/b-roll.mp4",
"timing": {
"startTime": 15,
"endTime": 25
},
"position": { "anchor": "center" },
"size": {
"width": "60%",
"height": "60%",
"fit": "contain"
},
"effects": {
"fadeIn": { "duration": 0.5 },
"fadeOut": { "duration": 0.5 }
},
"zIndex": 20
}
]
}Multiple Camera Angles
Show multiple camera angles simultaneously:
{
"fileUrl": "https://example.com/main-stage.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/camera-1.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "top-left" },
"size": { "width": "30%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/camera-2.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "top-right" },
"size": { "width": "30%", "fit": "cover" },
"zIndex": 10
}
]
}Looping Background Video
Add a looping video background:
{
"fileUrl": "https://example.com/main-content.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/animated-background.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "center" },
"size": { "width": "100%" },
"effects": { "opacity": 0.3 },
"loop": true,
"zIndex": 1
}
]
}Reaction Video Overlay
Add a reaction video in the corner:
{
"fileUrl": "https://example.com/content.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/reaction.mp4",
"timing": {
"startTime": 10,
"endTime": 30
},
"position": { "anchor": "bottom-left" },
"size": {
"width": "25%",
"fit": "cover"
},
"effects": {
"fadeIn": { "duration": 0.3 },
"fadeOut": { "duration": 0.3 }
},
"zIndex": 50
}
]
}Common Use Cases
Tutorial with Webcam PiP
Screen recording with instructor webcam:
{
"fileUrl": "https://example.com/screen-recording.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/instructor-webcam.mp4",
"timing": { "entireVideo": true },
"position": { "x": "85%", "y": "15%" },
"size": {
"width": "20%",
"fit": "cover"
},
"zIndex": 100
},
{
"type": "image",
"url": "https://example.com/webcam-border.png",
"timing": { "entireVideo": true },
"position": { "x": "85%", "y": "15%" },
"size": { "width": "22%" },
"zIndex": 101
}
]
}Split Screen Comparison
Compare two videos side by side:
{
"fileUrl": "https://example.com/background.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/video-left.mp4",
"timing": { "entireVideo": true },
"position": { "x": "25%", "y": "50%" },
"size": {
"width": "45%",
"fit": "contain"
},
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/video-right.mp4",
"timing": { "entireVideo": true },
"position": { "x": "75%", "y": "50%" },
"size": {
"width": "45%",
"fit": "contain"
},
"zIndex": 10
}
]
}Product Showcase
Main video with detailed product shots:
{
"fileUrl": "https://example.com/product-overview.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/detail-closeup.mp4",
"timing": { "startTime": 10, "endTime": 20 },
"position": { "anchor": "top-right" },
"size": { "width": "35%", "fit": "cover" },
"effects": {
"fadeIn": { "duration": 0.5, "easing": "ease-in" },
"fadeOut": { "duration": 0.5, "easing": "ease-out" }
},
"zIndex": 20
}
]
}Gaming Overlay
Game footage with facecam:
{
"fileUrl": "https://example.com/gameplay.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/facecam.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "bottom-left" },
"size": {
"width": "20%",
"fit": "cover"
},
"zIndex": 50
},
{
"type": "image",
"url": "https://example.com/facecam-frame.png",
"timing": { "entireVideo": true },
"position": { "anchor": "bottom-left" },
"size": { "width": "22%" },
"zIndex": 51
}
]
}Testimonial Collage
Multiple testimonial videos:
{
"fileUrl": "https://example.com/intro.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/testimonial-1.mp4",
"timing": { "startTime": 5, "endTime": 15 },
"position": { "x": "25%", "y": "30%" },
"size": { "width": "30%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/testimonial-2.mp4",
"timing": { "startTime": 5, "endTime": 15 },
"position": { "x": "75%", "y": "30%" },
"size": { "width": "30%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/testimonial-3.mp4",
"timing": { "startTime": 5, "endTime": 15 },
"position": { "x": "50%", "y": "70%" },
"size": { "width": "30%", "fit": "cover" },
"zIndex": 10
}
]
}Interview Picture-in-Picture
Host and guest in PiP layout:
{
"fileUrl": "https://example.com/host-camera.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/guest-camera.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "bottom-right" },
"size": {
"width": "30%",
"fit": "cover"
},
"zIndex": 10
}
]
}Advanced Examples
Sequential Video Overlays
Show different overlays at different times:
{
"fileUrl": "https://example.com/base.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/overlay-1.mp4",
"timing": { "startTime": 0, "endTime": 10 },
"position": { "anchor": "top-right" },
"size": { "width": "30%" },
"effects": {
"fadeIn": { "duration": 0.3 },
"fadeOut": { "duration": 0.3 }
},
"zIndex": 20
},
{
"type": "video",
"url": "https://example.com/overlay-2.mp4",
"timing": { "startTime": 15, "endTime": 25 },
"position": { "anchor": "top-right" },
"size": { "width": "30%" },
"effects": {
"fadeIn": { "duration": 0.3 },
"fadeOut": { "duration": 0.3 }
},
"zIndex": 20
},
{
"type": "video",
"url": "https://example.com/overlay-3.mp4",
"timing": { "startTime": 30, "endTime": 40 },
"position": { "anchor": "top-right" },
"size": { "width": "30%" },
"effects": {
"fadeIn": { "duration": 0.3 },
"fadeOut": { "duration": 0.3 }
},
"zIndex": 20
}
]
}Layered Video Composition
Multiple layers of video overlays:
{
"fileUrl": "https://example.com/base.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/background-layer.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "center" },
"size": { "width": "100%" },
"effects": { "opacity": 0.2 },
"loop": true,
"zIndex": 1
},
{
"type": "video",
"url": "https://example.com/middle-layer.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "center" },
"size": { "width": "70%" },
"effects": { "opacity": 0.6 },
"zIndex": 5
},
{
"type": "video",
"url": "https://example.com/foreground.mp4",
"timing": { "entireVideo": true },
"position": { "anchor": "bottom-right" },
"size": { "width": "25%" },
"zIndex": 10
}
]
}Dynamic Grid Layout
Create a video grid:
{
"fileUrl": "https://example.com/background.mp4",
"elements": [
{
"type": "video",
"url": "https://example.com/grid-1.mp4",
"timing": { "entireVideo": true },
"position": { "x": "25%", "y": "25%" },
"size": { "width": "40%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/grid-2.mp4",
"timing": { "entireVideo": true },
"position": { "x": "75%", "y": "25%" },
"size": { "width": "40%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/grid-3.mp4",
"timing": { "entireVideo": true },
"position": { "x": "25%", "y": "75%" },
"size": { "width": "40%", "fit": "cover" },
"zIndex": 10
},
{
"type": "video",
"url": "https://example.com/grid-4.mp4",
"timing": { "entireVideo": true },
"position": { "x": "75%", "y": "75%" },
"size": { "width": "40%", "fit": "cover" },
"zIndex": 10
}
]
}Best Practices
Video Optimization
Optimize video overlays before uploading: - Use efficient codecs (H.264 for MP4) - Compress videos to reasonable bitrates - Match or reduce resolution for overlays - Remove unnecessary audio tracks - Limit file sizes for faster processing
Performance Considerations
Processing impact:
- Each video overlay significantly increases processing time
- Multiple overlays compound the processing load
- Use pre-rendered overlays when possible
- Consider video duration and resolution
Optimization tips:
- Pre-encode overlays to match base video specs
- Use lower resolution for small overlays (PiP doesn't need 4K)
- Limit simultaneous overlays
- Use shorter clips when appropriate
Size and Position
PiP sizing:
- Standard PiP: 20-30% of video width
- Small corner: 15-20%
- Large feature: 40-50%
Safe zones:
- Keep overlays 5-10% from edges
- Avoid important areas of base video
- Test on different aspect ratios
Position strategy:
{
"position": { "x": "85%", "y": "85%" },
"size": { "width": "20%" }
}This creates a nice margin from the corner.
Timing Best Practices
Sync with content:
- Show webcam when speaking
- Display B-roll during relevant topics
- Time reactions to match moments
Use transitions:
{
"effects": {
"fadeIn": { "duration": 0.5, "easing": "ease-in-out" },
"fadeOut": { "duration": 0.5, "easing": "ease-in-out" }
}
}Loop considerations:
- Use loop for short decorative videos
- Don't loop for content-specific overlays
- Match timing to overlay video duration
Audio Considerations
Remember: Video overlay audio is automatically disabled. If you need audio from an overlay:
- Extract audio from the overlay video
- Add it as an Audio Element
- Sync the timing with the video overlay
Example with synchronized audio:
{
"elements": [
{
"type": "video",
"url": "https://example.com/pip-video.mp4",
"timing": { "startTime": 10, "endTime": 30 },
"position": { "anchor": "bottom-right" },
"size": { "width": "25%" },
"zIndex": 10
},
{
"type": "audio",
"url": "https://example.com/pip-audio.mp3",
"timing": { "startTime": 10, "endTime": 30 },
"effects": { "volume": 0.8 }
}
]
}Fit Modes
Use cover for PiP and cameras:
{ "fit": "cover" }Fills the space completely, crops if needed.
Use contain for content display:
{ "fit": "contain" }Shows entire overlay, may have letterboxing.
Troubleshooting
Video Overlay Not Appearing
Check:
- URL is publicly accessible
- Video format is supported (MP4 recommended)
- Timing is within base video duration
- Size is not 0 or negative
- zIndex is appropriate
Video Overlay Has No Audio
This is expected behavior. Video overlays have audio disabled by default. See Audio Handling above.
Poor Playback Quality
Solutions:
- Reduce overlay resolution
- Use efficient codecs (H.264)
- Compress overlay videos
- Match base video framerate
- Optimize bitrate
Processing Takes Too Long
Solutions:
- Reduce number of overlays
- Use shorter overlay clips
- Compress overlay videos
- Lower overlay resolution
- Pre-encode to match base video
Video Appears Distorted
Solutions:
- Use appropriate
fitmode - Check source video aspect ratio
- Verify size percentages
- Test with different fit modes
Overlay Doesn't Loop
Check:
{
"loop": true
}Also verify:
- Timing duration is longer than overlay duration
- Overlay video is valid
- No errors in processing logs