VideoCascadeLogo
VideoCascade

Elements Overview

Understanding the VideoCascade element system for overlays and audio

Elements are powerful overlays and audio tracks that you can add to your videos during processing. They allow you to create rich, dynamic video content by layering images, GIFs, video overlays, and audio tracks on top of your base video.

What Are Elements?

Elements are JSON objects that define visual or audio components to be added to your video. Each element specifies:

  • What to add (URL to the media)
  • When to show it (timing configuration)
  • Where to place it (position and size)
  • How it should appear (visual or audio effects)

Element Types

VideoCascadesupports four types of elements:

Common Properties

All visual elements (images, GIFs, video overlays) share these common properties:

Timing Configuration

Control when an element appears in your video:

interface TimingConfig {
  startTime?: number; // Start time in seconds
  endTime?: number; // End time in seconds
  entireVideo?: boolean; // Show for entire video duration
}

Examples:

  • Show for 5 seconds: { startTime: 0, endTime: 5 }
  • Show from 10s to 20s: { startTime: 10, endTime: 20 }
  • Show entire video: { entireVideo: true }

Position Configuration

Control where an element appears on the video:

interface PositionConfig {
  anchor?:
    | 'top-left'
    | 'top-center'
    | 'top-right'
    | 'center-left'
    | 'center'
    | 'center-right'
    | 'bottom-left'
    | 'bottom-center'
    | 'bottom-right';
  x?: string; // Percentage: "50%", "10%"
  y?: string; // Percentage: "50%", "10%"
}

Anchor Positions:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ top-left    top-center  top-right β”‚
β”‚                                   β”‚
β”‚ center-left   center  center-rightβ”‚
β”‚                                   β”‚
β”‚bottom-left bottom-center bottom-rightβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Position Methods:

  • Anchor-based: Use predefined positions like "top-right", "center"
  • Percentage-based: Use x and y for precise control like { x: "75%", y: "25%" }

You can use either anchor OR x/y coordinates, but not both. Anchor positions are easier for common placements, while x/y gives you pixel-perfect control.

Size Configuration

Control the size of visual elements:

interface SizeConfig {
  width?: number | string; // Pixels (200) or percentage ("20%")
  height?: number | string; // Pixels (100) or percentage ("10%")
  fit?: 'cover' | 'contain'; // How to fit the element
}

Fit Modes:

  • cover: Element fills the specified dimensions, may crop
  • contain: Element fits within dimensions, maintains aspect ratio

Visual Effects

Add fade transitions and opacity to visual elements:

interface VisualEffects {
  opacity?: number; // 0 (transparent) to 1 (opaque)
  fadeIn?: FadeConfig; // Fade in transition
  fadeOut?: FadeConfig; // Fade out transition
}

interface FadeConfig {
  duration: number; // Duration in seconds
  easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
}

Z-Index Layering

Control the stacking order of multiple elements:

zIndex?: number;  // Higher values appear on top

Elements are rendered in order of their zIndex value (lowest to highest). Elements with the same zIndex are rendered in the order they appear in the array.

Element Array Structure

Elements are passed as an array in your video processing request:

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/video.mp4",
    "elements": [
      {
        "type": "image",
        "url": "https://example.com/logo.png",
        "timing": { "entireVideo": true },
        "position": { "anchor": "top-right" },
        "size": { "width": "15%" },
        "effects": { "opacity": 0.9 },
        "zIndex": 10
      },
      {
        "type": "audio",
        "url": "https://example.com/music.mp3",
        "timing": { "entireVideo": true },
        "effects": { "volume": 0.3 },
        "loop": true
      }
    ]
  }'
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/video.mp4',
    elements: [
      {
        type: 'image',
        url: 'https://example.com/logo.png',
        timing: { entireVideo: true },
        position: { anchor: 'top-right' },
        size: { width: '15%' },
        effects: { opacity: 0.9 },
        zIndex: 10,
      },
      {
        type: 'audio',
        url: 'https://example.com/music.mp3',
        timing: { entireVideo: true },
        effects: { volume: 0.3 },
        loop: true,
      },
    ],
  }),
});
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/video.mp4',
'elements': [
{
'type': 'image',
'url': 'https://example.com/logo.png',
'timing': {'entireVideo': True},
'position': {'anchor': 'top-right'},
'size': {'width': '15%'},
'effects': {'opacity': 0.9},
'zIndex': 10,
},
{
'type': 'audio',
'url': 'https://example.com/music.mp3',
'timing': {'entireVideo': True},
'effects': {'volume': 0.3},
'loop': True,
},
],
}
)
interface VideoRequest {
  fileUrl: string;
  elements: Element[];
}

interface Element {
  type: 'image' | 'gif' | 'video' | 'audio';
  url: string;
  timing: TimingConfig;
  position?: PositionConfig;
  size?: SizeConfig;
  effects?: VisualEffects | AudioEffects;
  zIndex?: number;
  loop?: boolean;
}

const request: VideoRequest = {
  fileUrl: 'https://example.com/video.mp4',
  elements: [
    {
      type: 'image',
      url: 'https://example.com/logo.png',
      timing: { entireVideo: true },
      position: { anchor: 'top-right' },
      size: { width: '15%' },
      effects: { opacity: 0.9 },
      zIndex: 10,
    },
    {
      type: 'audio',
      url: 'https://example.com/music.mp3',
      timing: { entireVideo: true },
      effects: { volume: 0.3 },
      loop: true,
    },
  ],
};

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(request),
});

Processing Order and Layering

Elements are processed in a specific order to ensure proper rendering:

  1. Base Video: Your original video is the bottom layer
  2. Visual Elements: Images, GIFs, and video overlays are layered on top
    • Elements are sorted by zIndex (lowest to highest)
    • Same zIndex values use array order
  3. Audio Elements: Audio tracks are mixed together with the base video audio

Layering Example:

{
  "elements": [
    {
      "type": "image",
      "url": "https://example.com/background.png",
      "zIndex": 1,
      "comment": "Bottom layer"
    },
    {
      "type": "video",
      "url": "https://example.com/pip.mp4",
      "zIndex": 5,
      "comment": "Middle layer"
    },
    {
      "type": "image",
      "url": "https://example.com/watermark.png",
      "zIndex": 10,
      "comment": "Top layer"
    }
  ]
}

Performance Tip: Each element adds processing time. For best performance, optimize your images and videos before uploading, and use only the elements you need.

Common Use Cases

Branding and Watermarks

Add your logo or watermark to all videos:

{
  "type": "image",
  "url": "https://example.com/logo.png",
  "timing": { "entireVideo": true },
  "position": { "anchor": "bottom-right" },
  "size": { "width": "15%" },
  "effects": { "opacity": 0.7 },
  "zIndex": 100
}

Lower Thirds

Add name plates and titles to videos:

{
  "type": "image",
  "url": "https://example.com/lower-third.png",
  "timing": { "startTime": 0, "endTime": 5 },
  "position": { "anchor": "bottom-center" },
  "size": { "width": "80%" },
  "effects": {
    "fadeIn": { "duration": 0.5 },
    "fadeOut": { "duration": 0.5 }
  }
}

Picture-in-Picture

Add a webcam or reaction video overlay:

{
  "type": "video",
  "url": "https://example.com/webcam.mp4",
  "timing": { "entireVideo": true },
  "position": { "anchor": "bottom-right" },
  "size": { "width": "25%", "fit": "cover" },
  "zIndex": 10
}

Background Music

Add background music with volume control:

{
  "type": "audio",
  "url": "https://example.com/background-music.mp3",
  "timing": { "entireVideo": true },
  "effects": {
    "volume": 0.2,
    "fadeIn": { "duration": 2 },
    "fadeOut": { "duration": 3 }
  },
  "loop": true
}

Animated Reactions

Add GIF reactions at specific moments:

{
  "type": "gif",
  "url": "https://example.com/celebration.gif",
  "timing": { "startTime": 30, "endTime": 35 },
  "position": { "anchor": "center" },
  "size": { "width": "30%" },
  "loop": true
}

Best Practices

Performance Optimization

  • Optimize media files: Compress images and videos before uploading
  • Use appropriate sizes: Don't use 4K images for small overlays
  • Limit element count: Each element increases processing time
  • Use efficient formats: PNG for transparency, JPEG for photos

Timing Strategies

  • Align with content: Time elements to match video content
  • Use fade transitions: Smooth transitions look more professional
  • Test timing: Preview your elements before final processing

Position and Size

  • Mobile-friendly: Test your layout on different aspect ratios
  • Safe zones: Keep important elements away from edges
  • Maintain aspect ratios: Use fit: "contain" to prevent distortion
  • Consistent sizing: Use percentages for responsive layouts

Z-Index Management

  • Use spacing: Space out z-index values (10, 20, 30) for easier insertion
  • Logical ordering: Background elements (1-10), content (11-50), UI (51-100)
  • Document layers: Comment your element order for team clarity

Type Definitions

Complete TypeScript interfaces for all element types:

// Base types
interface TimingConfig {
  startTime?: number;
  endTime?: number;
  entireVideo?: boolean;
}

interface PositionConfig {
  anchor?:
    | 'top-left'
    | 'top-center'
    | 'top-right'
    | 'center-left'
    | 'center'
    | 'center-right'
    | 'bottom-left'
    | 'bottom-center'
    | 'bottom-right';
  x?: string;
  y?: string;
}

interface SizeConfig {
  width?: number | string;
  height?: number | string;
  fit?: 'cover' | 'contain';
}

interface VisualEffects {
  opacity?: number;
  fadeIn?: FadeConfig;
  fadeOut?: FadeConfig;
}

interface AudioEffects {
  volume?: number;
  fadeIn?: FadeConfig;
  fadeOut?: FadeConfig;
}

interface FadeConfig {
  duration: number;
  easing?: 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
}

// Element types
interface ImageElement {
  type: 'image';
  url: string;
  timing: TimingConfig;
  position: PositionConfig;
  size: SizeConfig;
  effects?: VisualEffects;
  zIndex?: number;
}

interface GifElement {
  type: 'gif';
  url: string;
  timing: TimingConfig;
  position: PositionConfig;
  size: SizeConfig;
  effects?: VisualEffects;
  zIndex?: number;
  loop?: boolean;
}

interface VideoOverlayElement {
  type: 'video';
  url: string;
  timing: TimingConfig;
  position: PositionConfig;
  size: SizeConfig;
  effects?: VisualEffects;
  zIndex?: number;
  loop?: boolean;
}

interface AudioElement {
  type: 'audio';
  url: string;
  timing: TimingConfig;
  effects?: AudioEffects;
  loop?: boolean;
}

type Element = ImageElement | GifElement | VideoOverlayElement | AudioElement;

Next Steps

Explore detailed documentation for each element type: