Skip to content
sailscastshqPublic

About

Deterministic video rendering with Vue

Resources

Stars

77 stars

Watchers

1 watching

Forks

Repository files navigation

Pellicule

Fund my work on FLOSSAfrica

Deterministic video rendering with Vue.

Write Vue components. Render videos.

Installation

npm install pellicule

Quick Start

1. Create a video component

<script setup>
import { useFrame, interpolate, Easing } from 'pellicule'
import { computed } from 'vue'

const frame = useFrame()
const opacity = computed(() =>
  interpolate(frame.value, [0, 30], [0, 1], { easing: Easing.easeOut })
)
</script>

<template>
  <div class="video" :style="{ opacity }">
    <h1>Hello, Pellicule!</h1>
  </div>
</template>

<style>
.video {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0a0a0f;
  color: white;
}
</style>

2. Render it

npx pellicule Video.vue -d 90 -o hello.mp4

CLI Options

Flag Description Default
-o, --output Output file path ./output.mp4
--preset Output preset (mp4, webm) mp4
--quality Output quality (draft, standard, high) standard
-d, --duration Duration in frames 90
-A, --duration-from-audio Use the audio file length as total duration false
-f, --fps Frames per second 30
-w, --width Video width 1920
-h, --height Video height 1080
-a, --audio Audio file to mux into the export none

Example output commands:

# Default MP4 (H.264 + AAC)
npx pellicule Video.vue

# WebM output
npx pellicule Video.vue --preset webm

# Higher-quality MP4
npx pellicule Video.vue --quality high

# Let the soundtrack define total duration
npx pellicule Karaoke.vue --audio song.mp3 --duration-from-audio

API

Composables

  • useFrame() - Get the current frame number as a reactive ref
  • useVideoConfig() - Access video configuration (fps, duration, dimensions)

Animation Utilities

  • interpolate(frame, inputRange, outputRange, options) - Map values between ranges
  • sequence(frame, steps) - Chain multiple animations together
  • secondsToFrames(seconds, fps) - Turn audio or lyric timings into whole frames
  • framesToSeconds(frames, fps) - Convert frame counts back to seconds
  • Easing - Built-in easing functions: linear, easeIn, easeOut, easeInOut

Audio-Aware Workflow

  • Add audio to defineVideoConfig() or pass --audio <file> to mux a soundtrack into the final export.
  • Add --duration-from-audio when you want Pellicule to derive durationInFrames from the probed audio length.
  • pellicule dev keeps preview audio in sync with play, pause, step, and scrub controls when an audio track is present.

How It Works

  1. Vite bundles your Vue component
  2. Playwright renders each frame in a headless browser
  3. FFmpeg encodes the frames into the selected output format

The rendering is deterministic - the same component produces the exact same video every time.

Requirements

  • Node.js 18+
  • FFmpeg installed and in PATH
  • Vue 3.x

Rsbuild 2 / Shipwright

The Rsbuild adapter requires @rsbuild/core ^2.2.5 and @rsbuild/plugin-vue ^2.0.1. Upgrade both together:

npm install -D @rsbuild/core@^2.2.5 @rsbuild/plugin-vue@^2.0.1

Rsbuild 2 requires Node.js ^20.19.0 || >=22.12.0. Rsbuild 1 is no longer supported by this adapter. Vite-based projects keep their existing build path.

Render the checked-in Rsbuild demo from the repository root:

npm ci
node packages/core/bin/cli.js examples/rsbuild/Video.vue --bundler rsbuild --config examples/rsbuild/video.config.mjs --quality high -o rsbuild-demo.mp4

See the demo notes for reproduction and release preparation for migration details.

Documentation

https://docs.sailscasts.com/pellicule

License

MIT

About

Deterministic video rendering with Vue

Resources

Stars

77 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages