Footage

A footage clip is a <video> element on the composition's timeline: Kinetic seeks it to the frame for the clock's time, plays it while the clock plays, and waits for it in check() and render().

Kinetic plays each clip itself, so it does not apply loop, autoplay or controls on the element. A footage clip plays its sound only with data-has-audio="true", and takes muted otherwise. data-remap gives a clip a speed ramp, and a file with keyframes far apart seeks slowly.

Footage

A footage clip is a <video> element with data-start inside the composition root. Kinetic seeks each clip to the frame for the clock's time, plays it while the clock plays, and waits for it in check() and render().

<video id="crowd" src="crowd.mp4" data-start="2" data-duration="5" data-media-start="12.5" muted playsinline></video>
<video id="talk" src="talk.mp4" data-start="intro" data-has-audio="true" data-volume="0.9" data-fade-out="0.5" playsinline></video>
<video id="rush" src="rush.webm" data-start="7" data-duration="2" data-playback-rate="2" muted playsinline></video>
AttributeMeaning
data-start, data-duration, data-endTimed like any clip (Timing). Without data-duration or data-end, the clip runs for the rest of its file from data-media-start, at its rate, a length read from the file at readiness, and a clip whose data-start refers to it starts where that file ends.
data-media-startSeconds into the file where the clip starts, 0 by default, with a data-playback-start on the clip read first, as the runtime reads it. With no data-duration or data-end, a media start at or past the file's end lasts no time, so the clip is never shown, and development builds warn (KN-139).
data-playback-rateThe file's seconds per composition second, from 0.1 to 10, and 1 by default. A value outside that range is clamped, and development builds warn (KN-139).
data-remapA speed ramp (Speed ramps).
mutedThe picture alone.
data-has-audio="true"The clip's sound plays, as an audio clip, in the preview, in the render's mix and in level() and spectrum(). With muted as well, the sound plays, and development builds warn that the two contradict (KN-139).
data-volume, data-fade-in, data-fade-outThe sound's gain and fades, as for an <audio> clip, with data-has-audio="true".

The frame for a time

At composition time t, a clip that starts at s, ends at e and starts m seconds into its file at rate r is at m + (min(max(t, s), e) - s) × r in its file, at most the file's length. It shows the source frame on screen 1 ms after that time.

  • For footage at the composition's own frame rate, that is the frame with the same number. The 1 ms covers a seek to the exact time showing the frame before it, since Chrome reads a time down to the microsecond and a WebM file stores each frame's time in whole milliseconds.
  • For footage at another rate, such as 29.97 fps in a 30 fps composition, it is the source frame that starts within 1 ms after the composition frame's time.
  • Past the end of the file its last frame holds.
  • Kinetic hides a clip outside its window as it hides any clip.
  • A file with no sound track and data-has-audio="true" is KN-135, and its development message suggests muted in place of data-has-audio.

Speed ramps

data-remap remaps the clip's time as a track is: data-remap="{ at: [0, 1, 2, 3], to: [0, 2, 2, 3] }", in the object syntax of data-bind-class (strict JSON reads too), with at seconds into the clip, increasing, and to seconds into the file from data-media-start, never going back. That one runs at double speed for a second, holds a frame for a second, then runs at single speed.

  • Between the keys the file time is linear, or shaped by ease as a track takes it, ease: 'smooth' for a ramp that passes the keys without a step; before the first key the first file time, and after the last the last, so the frame holds.
  • A clip with no data-duration or data-end lasts to the last key.
  • The sound of a clip with data-has-audio follows the same keys, its pitch moving with the speed, and is silent through a hold.
  • With a remap data-playback-rate is not applied, nor is a malformed remap or one whose ease overshoots (a spring, back, elastic, or a cubic-bezier() past 0 to 1), which would run the file time back, and development builds warn (KN-139); with the HyperFrames runtime on the page the runtime owns media and the remap is not applied there.

Seeks, playing, check() and render()

Seeks while paused

  • On a seek while the clock is paused, and on every seek of check() and render(), Kinetic pauses each clip, sets its currentTime to the clip's time in the file plus that millisecond, and holds the seek until the element fires seeked. A frame step, a scrub and a rendered frame then show the frame for their time.
  • A clip already at its time, or already seeking to it, is not given the time again.
  • The time a clip takes to seek is not part of the seek the guard measures (KN-170), since a file with keyframes far apart can take over 100 ms to seek, and the page's own code that runs while it does is not reported (KN-140, KN-142).
  • A clip before its window is held on its first frame, and one after it on the frame at its end, so a clip has its frame decoded when it enters its window.

While the clock plays

  • While the clock plays, each clip inside its window plays natively at its rate, and a clip outside its window is paused. A pause puts every clip back on the exact frame.
  • A clip that starts within 50 ms of its frame plays from where it is. Starting a clip stalls it about 45 ms in Chrome, and it plays on that far behind, so the frame drawn is the clock's frame or the one before it.
  • A playing clip is seeked again only when it is more than 50 ms of composition time from the clock and is neither seeking nor short of data, after a scrub, the loop back to 0 or a stall.
  • The element is kept muted, whatever its markup says, since its sound plays through Web Audio and its own sound would play it twice. When the browser blocks play(), the clip stays on its frame and the next seek tries again.

In check() and render()

  • check() loads the footage first, then compares each clip's currentTime, to the microsecond, between its two passes, so a clip sought to another time for the same seek fails it. That compares the time the clip was sought to, not the frame the decoder then shows.
  • render() captures each frame once every clip has seeked to it.

Loading and failure

Readiness waits for each clip's metadata and first frame, then for each clip to land on its frame for the clock's time, so when ready() resolves the page shows that frame. A clip with preload="none" is set to preload="auto" and loaded, since Kinetic plays the element itself.

A clip whose file fails to load, whose format the browser cannot play, or that has no src and no <source> is KN-138 (Failure), and the message gives the clip and its src. Chrome plays H.264, VP9 and AV1 in an MP4 or WebM file.

  • The development build's message gives the cause: the HTTP status, a format the browser cannot play, a decode error, a network error, or a server that could not be reached.
  • A <video> plays a file from another origin without CORS headers, so for such a file the development build's message says whether its server answered and gives no CORS advice. A render does need CORS (KN-204).
  • On a page opened from a file, the development build's message says the file is missing or cannot be played.
  • With the HyperFrames runtime on the page the runtime plays the media itself, so KN-138 does not occur (Rendering through HyperFrames).

Development warnings

Development builds warn once per clip (KN-139) about markup Kinetic does not apply, clamps or reads two ways, with a suggestion for each, and about a data-start that refers to no element (KN-113).

  • autoplay, controls or loop, since Kinetic plays the element itself.
  • data-automation, whose speed ramps Kinetic does not apply, so the clip plays at data-playback-rate; write the ramp as data-remap.
  • Neither muted nor data-has-audio="true". Such a clip plays no sound in Kinetic.
  • Both muted and data-has-audio="true", which contradict each other. Kinetic plays the sound, as data-has-audio asks.
  • A data-playback-rate outside 0.1 to 10, which is clamped.