thepublic.dev

Reelleer - Domain Model

Cover Image for Reelleer - Domain Model
The Public Dev
The Public Dev

Overview

The Reelleer domain model is built around a Timeline structure that represents a complete video composition. This model supports layered video editing with multiple tracks, clips, transitions, and effects - similar to professional video editing software but optimized for Instagram Reel creation.

Visual Timeline Example

Here's a more detailed view of how a complex timeline looks in practice:

Simple Timeline Example

Core Concepts

1. Timeline

The root container that defines the overall video composition:

  • Viewport: Output dimensions (1080x1920 for Instagram Reels)
  • Duration: Total timeline length in seconds
  • Tracks: Multiple layers of content that can be composited together

Timeline Schema

{
  "timeline": {
    "viewport": {
      "width": 1080,     // Instagram Reel width
      "height": 1920     // Instagram Reel height
    },
    "duration": 120.0,   // Total duration in seconds
    "tracks": [...]      // Array of track objects
  }
}

2. Tracks

Separate layers in the timeline, allowing for complex compositions:

  • Main Video Layer: Primary content (stories, videos, images)
  • Overlay Layer: Secondary content (logos, effects, text)
  • Each track can contain multiple clips and layer-wide effects

Track Schema

{
  "id": "track-1",
  "type": "video",           // "video", "audio", "overlay"
  "name": "Main Video Layer",
  "clips": [...],            // Array of clip objects
  "layerEffects": [...]      // Effects applied to entire track
}

3. Clips

Individual media elements placed on tracks:

  • Video Clips: MP4 files with audio and visual content
  • Image Clips: Static images (JPG, PNG) with specified duration
  • Each clip has positioning, timing, and effect properties

Video Clip Schema

{
  "id": "clip-1",
  "type": "video",
  "src": "video1.mp4",
  "mediaSize": { "width": 1920, "height": 1080 },
  "position": {
    "x": 0, "y": 0,          // Offset from anchor point
    "anchor": "center",       // "center", "top_left", "top_right", etc.
    "scale": 0.5,            // Scaling factor
    "fit": "cover"           // "cover", "contain", "fill", "none"
  },
  "start": 0.0,              // Start time on timeline
  "duration": 60.0,          // Clip duration
  "offset": 0.0,             // Offset into source media
  "transitionIn": {...},     // Entrance transition
  "transitionOut": {...},    // Exit transition
  "effects": [...],          // Visual/audio effects
  "audio": {...}             // Audio-specific properties
}

Image Clip Schema

{
  "id": "clip-2",
  "type": "image",
  "src": "image1.jpg",
  "mediaSize": { "width": 1200, "height": 1200 },
  "position": {...},         // Same as video
  "start": 60.0,
  "duration": 30.0,          // How long to display
  "transitionIn": {...},
  "transitionOut": {...},
  "effects": [...]
}

4. Transitions

Smooth connections between clips or tracks:

  • Clip Transitions: Between consecutive clips on the same track
  • Complex Transitions: Advanced multi-keyframe animations
  • Support for various easing functions and parameters

Simple Transitions

{
  "type": "fade_in",
  "duration": 1.0,
  "params": {}
}

Complex Transitions

{
  "type": "morph",
  "duration": 3.0,
  "params": {
    "keyframes": [
      { "time": 0.0, "scale": 1.0, "rotation": 0, "opacity": 1.0 },
      { "time": 0.5, "scale": 1.5, "rotation": 180, "opacity": 0.5 },
      { "time": 1.0, "scale": 1.0, "rotation": 360, "opacity": 1.0 }
    ],
    "blur_amount": 2.0,
    "color_shift": { "hue": 30, "saturation": 1.2 }
  }
}

Position System

The positioning system allows precise control over media placement:

The positioning system allows precise control over media placement:

  • Anchor Points: Define the reference point for positioning

    • center: Center of the viewport
    • top_left, top_right, bottom_left, bottom_right: Corner anchors
    • top_center, bottom_center, left_center, right_center: Edge centers
  • Fit Modes: Control how media is scaled to fit

    • cover: Scale to fill viewport, crop if necessary
    • contain: Scale to fit within viewport, letterbox if necessary
    • fill: Stretch to exact viewport dimensions
    • none: Use original size

Effects System

Effects can be applied at multiple levels:

Clip-Level Effects

"effects": [
  { "type": "color_correction", "params": { "brightness": 1.1, "contrast": 1.2 } },
  { "type": "stabilization", "params": {} },
  { "type": "chroma_key", "params": { "color": "#00FF00" } }
]

Track-Level Effects

"layerEffects": [
  { "type": "opacity", "value": 0.9 }
]

Global Effects

"globalEffects": [
  { "type": "lut", "name": "cinematic" }
]

Example: Complete Timeline

Here's a practical example showing how these components work together:

{
  "timeline": {
    "viewport": {
      "width": 1080,
      "height": 1920
    },
    "duration": 120.0,
    "tracks": [
      {
        "id": "track-1",
        "type": "video",
        "name": "Main Video Layer",
        "clips": [
          {
            "id": "clip-1",
            "type": "video",
            "src": "video1.mp4",
            "mediaSize": { "width": 1920, "height": 1080 },
            "position": {
              "x": 0,
              "y": 0,
              "anchor": "center",
              "scale": 0.5,
              "fit": "cover"
            },
            "start": 0.0,
            "duration": 60.0,
            "offset": 0.0,
            "transitionIn": {
              "type": "fade_in",
              "duration": 1.0,
              "params": {}
            },
            "transitionOut": {
              "type": "zoom_out",
              "duration": 2.0,
              "params": {
                "scale_to": 0.5,
                "easing": "ease_in"
              }
            },
            "effects": [
              { "type": "color_correction", "params": { "brightness": 1.1, "contrast": 1.2 } },
              { "type": "stabilization", "params": {} }
            ],
            "audio": {
              "volume": 0.8,
              "effects": [
                { "type": "fade_in", "duration": 2.0 }
              ]
            }
          },
          {
            "id": "clip-2",
            "type": "image",
            "src": "image1.jpg",
            "mediaSize": { "width": 1200, "height": 1200 },
            "position": {
              "x": 0,
              "y": 0,
              "anchor": "center",
              "scale": 1.0,
              "fit": "contain"
            },
            "start": 60.0,
            "duration": 30.0,
            "transitionIn": {
              "type": "wipe",
              "duration": 1.5,
              "params": {
                "direction": "left_to_right",
                "angle": 0,
                "softness": 0.1
              }
            },
            "transitionOut": {
              "type": "dissolve",
              "duration": 1.0,
              "params": {
                "opacity_curve": "ease_out"
              }
            },
            "effects": [
              { "type": "zoom_in", "params": { "scale": 1.2 } }
            ]
          },
          {
            "id": "clip-3",
            "type": "video",
            "src": "video2.mp4",
            "mediaSize": { "width": 1080, "height": 1920 },
            "position": {
              "x": 0,
              "y": 0,
              "anchor": "center",
              "scale": 1.0,
              "fit": "cover"
            },
            "start": 90.0,
            "duration": 30.0,
            "transitionIn": {
              "type": "slide",
              "duration": 2.5,
              "params": {
                "direction": "up",
                "easing": "ease_in_out"
              }
            },
            "transitionOut": {
              "type": "fade_out",
              "duration": 2.0,
              "params": {
                "easing": "linear"
              }
            },
            "effects": [
              { "type": "color_grade", "params": { "saturation": 1.3, "warmth": 0.2 } }
            ]
          }
        ],
        "layerEffects": [
          { "type": "opacity", "value": 0.9 }
        ]
      },
      {
        "id": "track-2",
        "type": "video",
        "name": "Overlay Layer",
        "clips": [
          {
            "id": "clip-4",
            "type": "video",
            "src": "overlay.mp4",
            "mediaSize": { "width": 1080, "height": 1920 },
            "position": {
              "x": 0,
              "y": 0,
              "anchor": "center",
              "scale": 1.0,
              "fit": "cover"
            },
            "start": 10.0,
            "duration": 20.0,
            "offset": 5.0,
            "effects": [
              { "type": "chroma_key", "params": { "color": "#00FF00" } }
            ]
          },
          {
            "id": "clip-5",
            "type": "image",
            "src": "logo.png",
            "mediaSize": { "width": 512, "height": 512 },
            "position": {
              "x": 20,
              "y": -20,
              "anchor": "top_right",
              "scale": 0.3,
              "fit": "none"
            },
            "start": 30.0,
            "duration": 60.0,
            "transition": {
              "type": "scale_in",
              "duration": 1.0,
              "params": {
                "scale_from": 0.0,
                "scale_to": 0.3,
                "rotation": 360,
                "easing": "bounce_out"
              }
            },
            "effects": [
              { "type": "drop_shadow", "params": { "blur": 5, "opacity": 0.5, "x": 2, "y": 2 } }
            ]
          }
        ]
      }
    ],
    "transitions": [
      {
        "id": "complex-transition-1",
        "fromClip": "clip-2",
        "toClip": "clip-3",
        "type": "morph",
        "duration": 3.0,
        "params": {
          "keyframes": [
            { "time": 0.0, "scale": 1.0, "rotation": 0, "opacity": 1.0 },
            { "time": 0.5, "scale": 1.5, "rotation": 180, "opacity": 0.5 },
            { "time": 1.0, "scale": 1.0, "rotation": 360, "opacity": 1.0 }
          ],
          "blur_amount": 2.0,
          "color_shift": { "hue": 30, "saturation": 1.2 }
        }
      }
    ],
    "globalEffects": [
      { "type": "lut", "name": "cinematic" }
    ]
  }

Other Considerations

Flexibility

  • Supports any number of tracks and clips
  • Extensible effects system
  • Multiple media types in single timeline

Professional Features

  • Keyframe-based animations
  • Audio synchronization
  • Advanced positioning system
  • Layer compositing

Instagram Optimization

  • Pre-configured for 9:16 aspect ratio
  • Optimized duration limits
  • Mobile-first design considerations

Mermaid Schema

Simple

%%{init: {'gantt': {'gridLineStartPadding': 350, 'fontSize': 18, 'sectionFontSize': 18, 'barHeight': 50, 'sectionHeight': 60}}}%%
gantt
    title Simple Reelleer Timeline (30 seconds)
    dateFormat X
    axisFormat %s
    
    section Overlay Track
    Logo                         :done, logo, 0, 30
    
    section Main Video Track
    Story 1                      :done, story1, 0, 10
    Story 2                      :done, story2, 10, 20
    Story 3                      :done, story3, 20, 30
    
    section Transitions
    Fade In                      :crit, fadein, 0, 1
    Cross Fade                   :crit, cross1, 9, 11
    Cross Fade                   :crit, cross2, 19, 21
    Fade Out                     :crit, fadeout, 29, 30
    
    section Audio
    Background Music             :active, music, 0, 30

Complex

%%{init: {'gantt': {'gridLineStartPadding': 350, 'fontSize': 11, 'sectionFontSize': 13, 'barHeight': 18, 'sectionHeight': 50}}}%%
gantt
    title Reelleer Timeline Model (120 seconds)
    dateFormat X
    axisFormat %s
    
    section Track 2 - Overlay
    Overlay Video (overlay.mp4)   :done, overlay1, 10, 30
    Logo (logo.png)              :done, logo1, 30, 90
    Text Animation (title.png)    :done, text1, 15, 45
    Watermark (brand.png)        :done, water1, 0, 120
    Call-to-Action (cta.png)     :done, cta1, 100, 120
    
    section Track 1 - Main Video
    Intro Video (intro.mp4)      :done, intro1, 0, 15
    Story 1 (story1.mp4)         :done, story1, 15, 35
    Story 2 (story2.jpg)         :done, story2, 35, 50
    Story 3 (story3.mp4)         :done, story3, 50, 70
    Product Shot (product.jpg)    :done, product1, 70, 85
    Story 4 (story4.mp4)         :done, story4, 85, 105
    Outro Video (outro.mp4)      :done, outro1, 105, 120
    
    section Transitions
    Fade In                      :crit, trans1, 0, 2
    Cross Dissolve               :crit, trans2, 14, 16
    Zoom In                      :crit, trans3, 34, 36
    Wipe Left                    :crit, trans4, 49, 51
    Morph Effect                 :crit, trans5, 69, 71
    Slide Up                     :crit, trans6, 84, 86
    Scale Out                    :crit, trans7, 104, 106
    Fade Out                     :crit, trans8, 118, 120
    
    section Audio Track
    Background Music             :active, music1, 0, 120
    Voice Over Intro             :active, voice1, 5, 20
    Sound Effects                :active, sfx1, 50, 55
    Voice Over Outro             :active, voice2, 100, 115
    
    section Global Effects
    Cinematic LUT                :active, global1, 0, 120
    Color Grading                :active, global2, 0, 120