Skip to content

marcuth/movie.js

Repository files navigation

Movie.js

Movie.js is a library built on top of fluent-ffmpeg designed to create templates for generating standardized videos with data—which can be static or dynamic. It simplifies the process of sequencing video, image, and audio clips into a final composition.

📦 Installation

Installation is straightforward; just use your preferred package manager. Here is an example using NPM:

npm i @marcuth/movie.js

Note: You must have FFMPEG installed on your system for this library to work.

🚀 Usage

Buy Me A Coffee

Template

The foundation for creating videos in Movie.js is the Template. This is where you define your clips and configuration.

import movie from "@marcuth/movie.js"

type RenderData = {
    heroImage: string
    backgroundVideo: string
} 

const template = movie.template<RenderData>({
    config: {
        format: "mp4",
        fps: 30,
        outputOptions: ["-preset ultrafast"] // optional ffmpeg output options
    },
    clips: [
        // ... your clips here
    ]
})

// Render the template with data
const result = await template.render({
    heroImage: "/path/to/image.png",
    backgroundVideo: "/path/to/video.mp4"
})

// Save the result
await result.toFile("output.mp4")

Clips

Clips are the building blocks of your video. They represent individual media segments like videos, images, or audio tracks.

Most file paths in clips support dynamic resolution:

path: ({ data, index }) => data.myPath

VideoClip

To insert a video segment:

movie.video({
    path: "assets/intro.mp4",
    fadeIn: 1, // seconds
    fadeOut: 1, // seconds
    subClip: [0, 5] // [start, duration] - Clip from 0s to 5s
})

ImageClip

To insert an image with optional scrolling/Ken Burns effect:

movie.image({
    path: ({ data }) => data.heroImage,
    duration: 5, // seconds
    width: 1920, // force resize width
    height: 1080, // force resize height
    scroll: {
        axis: "y", // "x", "y", or "auto"
        direction: "forward",
        easing: "easeInOut"
    },
    fadeIn: 0.5
})

AudioClip

To add audio (background music, sound effects):

movie.audio({
    path: "assets/music.mp3",
    volume: 0.5,
    fadeIn: 2,
    fadeOut: 2
})

TextClip

To create a simple text-on-color clip:

movie.text({
    text: ({ data }) => data.title,
    duration: 3,
    backgroundColor: "#000000",
    fontColor: "white",
    fontSize: 72,
    // x and y accept ffmpeg expressions
    x: "(w-text_w)/2", // default: centered
    y: "(h-text_h)/2", // default: centered
    fadeIn: 0.5,
    fadeOut: 0.5
})

Structural Clips

RepeatClip

If you need to loop over an array of data to generate clips:

movie.repeat({
    each: ({ data }) => data.items, // Array of items
    clip: (item, index) => movie.video({
        path: item.videoPath
    })
})

CompositionClip

Group multiple clips together. Useful for organizing sequences:

movie.composition({
    clips: [
        movie.video({ ... }),
        movie.video({ ... })
    ]
})

ConcatenationClip

Explicitly concatenate a list of clips:

movie.concatenation({
    clips: [ ... ]
})

🤝 Contributing

Want to contribute? Follow these steps:

  1. Fork the repository.
  2. Create a new branch (git checkout -b feature-new).
  3. Commit your changes (git commit -m 'Add new feature').
  4. Push to the branch (git push origin feature-new).
  5. Open a Pull Request.

📝 License

This project is licensed under the MIT License.

About

Movie.js is a library built on top of fluent-ffmpeg designed to create templates for generating standardized videos with data—which can be static or dynamic. It simplifies the process of sequencing video, image, and audio clips into a final composition.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors