Home/FIIVO DOCSALPHA
Open Editor

1. Introduction

Fiivo is a fully local, in-browser video editor built on WebCodecs, Canvas 2D and the Web Audio API. No uploads, no servers, no watermarks. Fiivo is currently in alpha — APIs and UI may change, but your projects are always saved locally.

  • Video, image, audio, text and procedural code layers on an unlimited-layer timeline.
  • Keyframes, easing curves, intro/outro animations and fully scriptable custom effects.
  • Hardware-accelerated MP4 export with offline audio mixing.

2. Quick Start

  • Add media: drag MP4/MP3/images directly onto the Asset panel, or click Upload.
  • Add to timeline: click the + button on any asset.
  • Preview: press Space to play/pause. Drag the ruler to scrub.
  • Edit: select a clip to open its properties. Drag directly on the canvas to move; drag corners to scale.
  • Export: click Export Video — an MP4 is rendered locally via WebCodecs.

3. Editor Overview

PanelLocationPurpose
Asset BinLeftAll imported media + code graphics. Drag & drop supported.
Preview CanvasCenterLive rendering. Drag to move, corner handles to scale, snapping guides included.
TimelineCenter-bottomLayered clips, ruler scrubbing, zoom, split, snap.
PropertiesRightTransforms, filters, crop, audio, keyframes, code, animations. Project settings when nothing is selected.
Layout controlsTop barCollapse either sidebar or the timeline. Drag panel dividers to resize; the layout is restored on your next visit.

4. Timeline & Clips

ActionHow
Play / PauseSpace
Split clip at playheadSelect clip, press S
Delete clipSelect clip, press Delete / Backspace
Move clipDrag horizontally; drag vertically to change layer
TrimDrag the left/right edge of a clip
Multi-selectShift-click clips — they move as a group
SnappingClips snap to playhead and other clip edges automatically
Ripple modeToggle Ripple in the toolbar. Deleting closes the selected time range; inserting shifts later clips on the target layer.
Create compoundSelect two or more tracks and use Group. The named result becomes one violet timeline clip and a reusable Asset.
Reuse sequenceAdd a sequence from Assets like other media. Each instance has independent timing and transforms.
Unpack compoundUse Ungroup in the timeline or Unpack to Tracks in Properties to restore editable child tracks.
ZoomZoom slider in the timeline toolbar

5. Keyframes

With a clip selected, open the Keyframes section in the Properties panel. Each keyframe stores a time offset (seconds from clip start) plus X, Y, scale and opacity. Fiivo interpolates between keyframes using the easing curve you pick per keyframe. Click Target to Editto drag that keyframe's state directly on the canvas.

EasingFeel
linearConstant, mechanical
easeOutQuadSmooth stop
easeInOutQuadSmooth start & stop
easeOutExpoFast start, slow stop
easeOutBackOvershoot / bounce
elasticWobbly, springy

6. Intro / Outro Animations

Presets applied automatically at clip boundaries, with adjustable duration (0.1–3s):

  • Intro: Smooth Fade, Slide Up, Pop/Scale — each with its own easing curve.
  • Outro: Fade Out, Slide Down, Shrink & Pop.

7. Custom Code Graphics

A code layer is a live Canvas 2D script driven by the playhead. Create one via Asset Bin → Code. The Code Graphic Studio combines a highlighted editor, live preview, attached project media, reusable parameters and local drafts. Attached media remain iterable through media and are also available through their stable alias, such as media.logo.

Your code runs as:

function (ctx, time, progress, media, params, width, height) { ... }
VariableTypeDescription
ctxCanvasRenderingContext2DDrawing context. Origin (0,0) is the layer position; the layer scale/opacity/rotation are already applied.
timenumberSeconds since the clip started.
progressnumber0.0 → 1.0 across the clip duration.
mediaArrayAttached images/videos (see below).
paramsObjectRead-only values defined in the studio, referenced by name.
width / heightnumberCurrent graphic canvas dimensions in pixels.

Each item in media:

MemberDescription
name / typeAsset name; "image" or "video".
width / heightNative pixel dimensions (0 until loaded).
readyTrue once the media can be drawn.
aliasStable property name used as media.alias.
draw({ x, y, scale, opacity, rotation })Draws the media centered at offset (x, y). All params optional — defaults: 0, 0, 1, 1, 0.

Example — orbiting an attached logo with a parameterized title:

if (media.logo?.ready) {
  media.logo.draw({
    x: Math.sin(time * 1.5) * 180,
    y: Math.cos(time * 1.5) * 90,
    scale: 0.45 + Math.sin(time * 2) * 0.05,
    rotation: Math.sin(time) * 8,
    opacity: 0.9
  });
}

ctx.fillStyle = '#38bdf8';
ctx.font = 'bold 42px Arial';
ctx.textAlign = 'center';
ctx.shadowColor = '#38bdf8';
ctx.shadowBlur = 20 * Math.abs(Math.sin(time * 2));
ctx.fillText(params.title || 'Built with Fiivo', 0, -160);

Because the layer position/scale/opacity are applied before your code runs, keyframes, intro/outro animations and custom effects all work on code layers too.

8. Custom Effects & Transitions

Custom effects are per-clip snippets that run inside a time window (relative to clip start). They receive progress (0→1 within the window) and a mutable state object — mutate it to transform the clip.

function (progress, state) { ... }
state fieldDescription
x, yPosition in canvas pixels
scaleScale multiplier
opacity0–1
zDepth (pseudo-3D, positive = further away)
rotateX, rotateYPitch / yaw in degrees (flattening effect)
rotationRoll in degrees

Built-in templates (Properties → Custom Effects → Add Template):

// Bounce
state.y += Math.abs(Math.sin(progress * Math.PI * 4)) * -100;

// 3D Barrel Roll
state.rotateY += progress * 360;

// Heartbeat Pulse
state.scale += Math.sin(progress * Math.PI * 4) * 0.2;

// Glitch Shake
state.x += (Math.random() - 0.5) * 20;

Effects and transitions are separate preset types. Effects modify one clip's state. A transition belongs to the incoming clip at an adjacent edit point and receives safe outgoing/incoming drawing handles.

A.draw({ x: -progress * width * 0.25, opacity: 1 - progress });
B.draw({ x: (1 - progress) * width * 0.25, opacity: progress });

Open the Transition Studio from the Effects & Graphics store. Select either clip beside an edit point, adjust duration and easing, then apply the transition. Personal presets remain in this browser.

9. Studios & Preset Library

The Effects & Graphics window separates immutable Fiivo presets from your personal library. Store cards include animated previews, preset type, code and asset indicators, aspect compatibility and the available add, preview, duplicate, edit and delete actions.

ItemBehavior
Fiivo presetsBuilt into the application. Adding or duplicating one never modifies the original.
Personal libraryGraphics and transitions saved in IndexedDB for this browser profile. They are not published to Fiivo.
Code Graphic StudioCodeMirror editor, live canvas, attached-media aliases, parameters, runtime errors and local drafts.
Transition StudioA/B clip selectors, live edit-point preview, duration, easing, sandbox diagnostics and save/apply actions.

A transition requires two linked visual clips on the same timeline layer. The outgoing clip must end exactly where the incoming clip begins. Images, videos and procedural code graphics can all be used as A/B inputs.

All user code runs in disposable, time-limited Web Workers. Network, browser storage and DOM capabilities are unavailable. Graphic code receives a restricted Canvas 2D environment; transition code can only submit validated operations through A.draw() and B.draw().

10. Crop & Color Filters

Use the Full, Proxy and Draft controls above the preview canvas to trade interactive resolution for smoother playback. This never changes project or export resolution.

Select an image or video clip and open Color Workspace for exposure, temperature, tint, hue, contrast, saturation and brightness. The live RGB histogram measures the graded frame; hold Original or the B key for source comparison. Built-in looks are editable starting points, and Apply creates one undoable edit.

  • Crop: images & videos — Properties → Open Crop Editor. Drag the sky-blue handles; cropping is baked into transforms and export.
  • Filters: brightness, contrast, saturation (0–200%) and hue-rotate (0–360°), applied live and in export.

11. Audio Editing

ControlDescription
Volume0–100% per clip (video clips included).
MuteSilence a clip without losing its volume setting.
Fade InChoose any duration up to the clip length, a starting level, and linear, ease-in, ease-out or smooth easing.
Fade OutChoose any duration up to the clip length, an ending level, and an independent easing curve.
TrimResize the clip edge, or use Split (S) + Delete.
WaveformsAudio and video clips show cached, normalized waveforms on the timeline.
Master meterThe timeline toolbar displays the live left and right output level during playback.
Export mixThe same volume envelopes heard in preview are rendered offline into an Opus stereo track at 48 kHz.

12. Captions & Subtitles

  • Use Captions in the timeline toolbar to import SRT or WebVTT files.
  • Each cue becomes an editable timed caption block. Edit its text, timing, font, color, placement, background, width and outline in Properties.
  • Caption rendering is shared by preview and export, so subtitles are burned into the exported video exactly as shown.
  • In .fivo projects, captions use type: "caption", with text in properties.text and visual options in properties.captionStyle.

13. Exporting Video

  • Engine: WebCodecs VideoEncoder (H.264, 8 Mbps) + Opus audio via mp4-muxer.
  • Every frame is decoded offline via MP4Box + VideoDecoder — export is frame-accurate, not a screen recording.
  • Supports the File System Access save dialog where available; otherwise downloads automatically.
  • Best experience: Chrome / Edge. Source videos should be MP4 (H.264).

14. Saving & .fivo Files

  • Auto-save: your project persists in the browser automatically — close the tab and restore later.
  • Save: downloads a .fivo file (JSON project description).
  • Open: import a .fivo. Media files are not embedded — use the relink button on each asset to point at your local files.
  • Version history: use the history button in the editor header to create or restore browser-local snapshots. Fiivo retains the latest 20 versions.
  • Recovery autosave: after project changes settle for six seconds, Fiivo records a recovery version separately from the live session save.

15. AI Project Templates

Because .fivo files are plain JSON, you can describe a whole video to any AI assistant and have it generate a complete Fiivo project for you. Just copy the system prompt below into your favorite LLM, describe your video idea, and import the resulting .fivo JSON file into Fiivo.

System Prompt for AI Generation

System Role: You are an expert Motion Graphics Engineer and JSON Architect for the Fiivo Video Editor, a proprietary, deterministic, browser-based Non-Linear Editor (NLE).

Task: Generate creative, valid .fivo JSON projects using procedural graphics, keyframes, transforms, effects and explicit A/B transitions. Prefer restrained, intentional motion over adding every feature to every clip.

Complete Fiivo Reference Project

This is the canonical project structure. It includes relinkable assets, adjacent clips, a procedural background, text, an effect and a transition. All timeline values are seconds.

{
  "version": "1.0",
  "name": "AI Product Intro",
  "settings": {
    "width": 1920,
    "height": 1080,
    "backgroundColor": "#09090b",
    "previewQuality": 0.5, "fps": 30
  },
  "duration": 10,
  "assets": [
    { "id": "asset_shot_a", "name": "shot-a.mp4", "type": "video", "url": "" },
    { "id": "asset_shot_b", "name": "shot-b.mp4", "type": "video", "url": "" },
    {
      "id": "asset_grid",
      "name": "Animated Grid",
      "type": "code",
      "url": "",
      "duration": 10,
      "graphicsCode": "ctx.fillStyle = '#081018'; ctx.fillRect(-width/2,-height/2,width,height); ctx.strokeStyle = 'rgba(56,189,248,.2)'; for(let x=-width/2;x<width/2;x+=80){ctx.beginPath();ctx.moveTo(x,-height/2);ctx.lineTo(x,height/2);ctx.stroke();}",
      "mediaLayers": [],
      "parameters": []
    }
  ],
  "tracks": [
    {
      "id": "track_grid",
      "name": "Animated Grid",
      "type": "code",
      "startFrame": 0,
      "endFrame": 10,
      "layer": 0,
      "properties": {
        "position": { "x": 960, "y": 540 },
        "scale": 1, "opacity": 1,
        "assetId": "asset_grid",
        "graphicsCode": "ctx.fillStyle = '#081018'; ctx.fillRect(-width/2,-height/2,width,height); ctx.strokeStyle = 'rgba(56,189,248,.2)'; for(let x=-width/2;x<width/2;x+=80){ctx.beginPath();ctx.moveTo(x,-height/2);ctx.lineTo(x,height/2);ctx.stroke();}",
        "mediaLayers": [],
        "codeParameters": {}
      }
    },
    {
      "id": "track_shot_a",
      "name": "Opening Shot",
      "type": "video",
      "startFrame": 0,
      "endFrame": 5,
      "layer": 1,
      "properties": {
        "position": { "x": 960, "y": 540 },
        "scale": 1, "opacity": 1,
        "assetId": "asset_shot_a", "src": "", "trimStart": 0,
        "volume": 1, "muted": false,
        "z": 0, "rotateX": 0, "rotateY": 0, "rotation": 0,
        "filters": { "brightness": 100, "contrast": 100, "saturation": 100, "hue": 0 },
        "crop": { "top": 0, "bottom": 0, "left": 0, "right": 0 },
        "customEffects": [
          { "id": "effect_drift", "startTime": 0, "endTime": 5, "code": "state.x += Math.sin(progress * Math.PI * 4) * 8;" }
        ]
      }
    },
    {
      "id": "track_shot_b",
      "name": "Feature Shot",
      "type": "video",
      "startFrame": 5,
      "endFrame": 10,
      "layer": 1,
      "properties": {
        "position": { "x": 960, "y": 540 },
        "scale": 1, "opacity": 1,
        "assetId": "asset_shot_b", "src": "", "trimStart": 0,
        "volume": 1, "muted": false,
        "filters": { "brightness": 100, "contrast": 100, "saturation": 100, "hue": 0 },
        "crop": { "top": 0, "bottom": 0, "left": 0, "right": 0 },
        "transition": {
          "id": "transition_cross_slide",
          "name": "Cross Slide",
          "duration": 0.65,
          "easing": "easeInOutCubic",
          "code": "A.draw({ x: -progress * width * 0.35, opacity: 1 - progress }); B.draw({ x: (1 - progress) * width * 0.35, opacity: progress });"
        }
      }
    },
    {
      "id": "track_title",
      "name": "Product Title",
      "type": "text",
      "startFrame": 0.4,
      "endFrame": 4.5,
      "layer": 2,
      "properties": {
        "position": { "x": 960, "y": 180 },
        "scale": 1, "opacity": 1,
        "text": "Build faster",
        "fontFamily": "Arial",
        "color": "#ffffff",
        "animation": { "type": "slideUp", "duration": 0.7, "easing": "easeOutExpo" },
        "outroAnimation": { "type": "fade", "duration": 0.5 }
      }
    }
  ]
}

Generation Rules

  • Return one raw JSON object only. Do not wrap it in Markdown or explanatory text.
  • Use unique string IDs. Every media track assetId must reference an item in assets.
  • Keep imported media URLs and matching track src values empty; the user relinks local files after import.
  • Use canvas-center coordinates: x is width / 2 and y is height / 2 for a centered layer.
  • Place backgrounds on lower layers and titles or overlays on higher layers.
  • Transitions belong to the incoming clip. Its startFrame must equal the outgoing clip endFrame, and both clips must share a layer.
  • Always include position, scale and opacity in every track properties object.
  • Reusable sequences use an asset with type: "sequence" and sequenceTracks. Timeline instances use type: "compound" with local children in properties.compoundTracks.
  • Write actual bounded code. Never output placeholders such as // animation goes here.

The Math & Code Engines

Fiivo executes visual code inside restricted, time-limited workers. Generated code must not use the DOM, network, storage, timers or module imports.

  • Procedural Graphics (graphicsCode): Only for type: "code". Vars: ctx, time, progress, media, params, width and height.
  • Custom Effects (customEffects[].code): For ANY track. Vars: state (mutable object with x, y, scale, opacity, rotateX, rotateY, rotation, z), progress (0.0 to 1.0 within effect window).
  • Transitions (transition.code): Stored on the incoming clip. Vars: A, B, progress, width and height. Only call A.draw() and B.draw().

Strict Allowed Enums

Do NOT invent animation types or easings. You must strictly use only these values:

  • Intro Animations: fade, slideUp, slideDown, scaleIn
  • Outro Animations: fade, slideDown, scaleOut
  • Easings: linear, easeOutQuad, easeInOutQuad, easeOutCubic, easeInOutCubic, easeOutExpo, easeOutBack, elastic

The Golden Example (Few-Shot Prompt)

Mimic this exact structure, nesting, and property naming for all generations:

{
  "version": "1.0", "name": "SaaS Demo", "duration": 10,
  "settings": { "width": 1920, "height": 1080, "backgroundColor": "#020617", "previewQuality": 0.5, "fps": 60 },
  "assets": [ { "id": "img1", "name": "ui.png", "type": "image", "url": "" } ],
  "tracks": [
    {
      "id": "t1", "name": "UI Reveal", "type": "image", "startFrame": 0, "endFrame": 10, "layer": 1,
      "properties": {
        "position": { "x": 960, "y": 540 }, "scale": 1, "opacity": 1, "assetId": "img1",
        "animation": { "type": "scaleIn", "duration": 1.2, "easing": "easeOutExpo" },
        "outroAnimation": { "type": "fade", "duration": 0.8 },
        "customEffects": [
          { "id": "fx1", "startTime": 0, "endTime": 10, "code": "state.y += Math.sin(progress * Math.PI * 4) * 20;" }
        ]
      }
    }
  ]
}

Workflow:Give this prompt to an AI, ask it to "Create a 15-second cyberpunk intro trailer", save its JSON output as my_trailer.fivo, and click Open in the Fiivo editor. Relink your local video/image assets, and the entire timeline, keyframes, and code layers will be ready to render!

16. AI Code Generation Prompts

Because Fiivo's graphicsCode and customEffects are sandboxed JavaScript, you can use AI to write complex SaaS trailers, particle systems, and glitch transitions. Copy these system prompts into your favorite LLM.

Prompt 1: Procedural Canvas Graphics
System Role: You are a Creative Coder specializing in HTML5 Canvas 2D API and motion graphics.
Task: Write a JavaScript function body for a video editor's procedural layer.
Variables available: 
- ctx (CanvasRenderingContext2D, origin 0,0 is center of layer)
- time (seconds since layer start)
- progress (0.0 to 1.0)
- media (attached images/videos with a .draw({x, y, scale, opacity, rotation}) method)
- params (read-only user-defined values)
- width and height (canvas dimensions)

Rules:
1. Use standard Canvas API (ctx.fillStyle, ctx.beginPath, ctx.arc, etc.).
2. If using media, check .ready and call its validated draw method.
3. Do not access DOM, network, storage, timers, modules, window, document or globalThis.
4. Keep loops bounded and do not wrap the result in a function declaration.
Prompt 2: Custom State Effects (Glitch, Bounce, 3D)
System Role: You are a Math & Animation Expert.
Task: Write a JavaScript snippet that mutates a video clip's transform state.
Variables available:
- progress (0.0 to 1.0 across the effect window)
- state (Mutable object: { x, y, scale, opacity, rotateX, rotateY, rotation, z })

Rules:
1. Mutate the state object directly (e.g., state.rotateY += progress * 360;).
2. Prefer deterministic Math.sin and Math.cos motion; avoid Math.random because it flickers between frames.
3. Keep it under 8 lines of code for performance.
Prompt 3: A/B Transitions
System Role: You design concise two-clip video transitions.
Task: Write a raw Fiivo transition code body.
Variables: A, B, progress (0..1), width, height.

Rules:
1. Call A.draw(options) and B.draw(options) exactly once each.
2. Options may contain only x, y, scale, opacity and rotation.
3. Both clips should fully cover the frame at the midpoint unless a deliberate dip is requested.
4. Do not use DOM, Canvas APIs, network, storage, timers or unbounded loops.
5. Return code only, without a function wrapper or Markdown fence.
Fiivo Docs · Alpha · Engineered by Muhammad Fasih Zaheer