VideoCascadeLogo
VideoCascade

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

PropertyTypeDescription
type'video'Must be "video"
urlstringURL to the video file (must be publicly accessible)
timingTimingConfigWhen to show the video overlay
positionPositionConfigWhere to place the video
sizeSizeConfigSize of the video overlay

Optional Properties

PropertyTypeDefaultDescription
effectsVisualEffectsundefinedVisual effects like opacity and fades
zIndexnumber0Stacking order (higher = on top)
loopbooleanfalseWhether 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:

  1. Extract audio from the overlay video
  2. Add it as an Audio Element
  3. 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:

  1. URL is publicly accessible
  2. Video format is supported (MP4 recommended)
  3. Timing is within base video duration
  4. Size is not 0 or negative
  5. 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 fit mode
  • 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

Next Steps