Docs

Everything the renderer understands today. See WHAT.md in the repo for the module-level design and for which attributes parse but have no effect yet.

Compositions are trees of custom elements. The renderer parses them into a typed program, resolves durations, compiles an ffmpeg filter graph, and returns an MP4. A vi-track is a lane; a vi-group is a run of things in one.

ELEMENTDESCRIPTIONATTRIBUTES
vi-compositionRoot. The output surface and frame rate. One per document.width, height, fps, background
vi-groupA run of things in one lane, played in order. The layer a bake freezes.id, start, start-after, end, duration, bake
vi-trackA lane. Parallel layers on one clock — a shot is a track, and so is a music bed.id, start, start-after, end, duration, bake
vi-videoPicture. duration="fill" stretches it to the slot a rigid sibling decided.src or id, cut, duration, loop, fit, scale, x, y, rotate, crop, speed, opacity, fade-in, fade-out, z
vi-imageStill picture. Same transform surface as vi-video.src or id, duration, loop, fit, scale, x, y, rotate, crop, opacity, fade-in, fade-out, z
vi-audioSound. A music bed is one of these beside a scene, never an attribute on it.src or id, cut, duration, start, gain, volume, fade-in, fade-out, muted
vi-textTypeset text from a fixed utility vocabulary — sizes, colours, safe areas.id, start, duration, class, z
vi-transitionSits between two siblings in a group and blends them. Its absence is a smash cut. Fade only today.type, duration
vi-gapTime with nothing in it. Cutting to black for two beats is a shot.duration
vi-captionsSpecified, not rendered yet. Emitted by the audio it sits inside.class, lang, word-timing, src
vi-animateSpecified, not rendered yet. Interpolates one property of its parent.property, from, to, duration, delay, ease

A scene, a bed timed against it, and a title card

<vi-composition width="1080" height="1920" fps="30" background="black">

  <vi-group id="sc1">

    <!-- The voice-over is rigid, so it sets the shot's length.
         The picture fills it, looping seamlessly if it is shorter. -->
    <vi-track id="sc1-01">
      <vi-video src="intro.mp4" duration="fill" loop="crossfade" />
      <vi-audio src="line-1.m4a" fade-in="0.2s" />
    </vi-track>

    <vi-transition type="fade" duration="0.5s" />

    <!-- An insert: push in on the eyes. -->
    <vi-track id="sc1-06" duration="1.5s">
      <vi-video src="eyes.mp4" duration="fill" scale="1.8" y="-12%" />
    </vi-track>

  </vi-group>

  <!-- The bed is its own lane, timed against the scene. -->
  <vi-track start="sc1" end="sc1">
    <vi-audio src="bed.m4a" duration="fill" gain="-16db" fade-out="2s" />
  </vi-track>

  <!-- Title card on top. Higher z draws above earlier layers. -->
  <vi-track start="sc1" end="sc1">
    <vi-text class="title-serif text-white safe-center" z="10" duration="fill">
      TERM SHEET: ROMA
    </vi-text>
  </vi-track>

</vi-composition>