JavaScript video editor, encoder, switcher - version 5.1.1

Architecture

The Movie Masher codebase is organized as a monorepo which is made available in GitHub as moviemasher/moviemasher.js. This repository contains and builds several packages which are made available in NPM:

All code is written in TypeScript as strongly-typed ECMAScript modules utilizing named exports. External libraries are imported as peer dependencies to simplify bundling. Any modern JavaScript transpiler should be able to treeshake, split, or otherwise repackage the code to produce a bundle best optimized for final delivery.

Repository Structure

  • dev - shared configuration and assets
  • docs - a local copy of this documentation
  • node_modules - installed module depedencies
  • packages - published NPM modules
    • client-react
    • moviemasher.js
    • server-express
    • theme-default
  • workspaces - example deployments
    • example-core
    • example-express
    • example-express-react
    • example-react

moviemasher.js

The core moviemasher.js NPM package has no dependencies, though portions do rely on browser APIs not natively available in all execution environments. It defines core interfaces into Movie Masher's data structures and classes, ultimately enabling playback and composition of a variety of media assets within both client and server contexts.

It includes the core Mash interface which organizes assets into an edit decision list (EDL) and supports JSON serialization for transport between client and server. It can be used in either context, though some methods are only valid in one or the other.

In the client content, Editor provides methods which represent each discrete edit as a collection of Actions, to support undo/redo history. It also provides [[Svgs]] representing the Tracks within the Mash for compositing within the browser. Learn more in the Styling Overview.

In the server context, RenderingProcess provides methods which produce media files from a Mash, using patterns and concepts established by FFmpeg like FilterGraphs. Learn more in the Rendering Overview.

server-express

The server-express NPM package depends on moviemasher.js plus express, sqlite, fluent-ffmpeg, node-media-server, and wtrc. It defines a collection of ExpressJS components responsible for housing content on a server and transforming it into rendered files and streams.

The ApiServer is called by the ApiClient component to map each Endpoint to an ApiCallback request before the client actually makes it. The base implementation just maps back to the same server, but subclasses can use this mechanism to dynamically route traffic to other servers. The client caches mapping based on a time-to-live (TTL) value supplied by the server, so routing can potentially be per-request. Learn more about customizing client interaction in the Server Developer Guide.

The DataServer and FileServer store and deliver user JSON data and media assets respectively. The base implementations use a local database and the file system, but subclasses can swap out homespun or cloud-based solutions.

The RenderingServer renders a Mash into common video, audio, or image formats while the StreamingServer streams a Cast in common formats. The default implementations both rely on Fluent FFmpeg which closely maps to FFmpeg arguments, so subclassing is possible. Learn more about server encoding in the Rendering Overview and Streaming Overview.

client-react

The client-react NPM package depends on moviemasher.js and theme-default plus react, with examples using react-dom. It defines dozens of interoperable ReactJS function components that can be combined to fit a wide variety of uses within a custom video editing application.

The ApiClient component provides a central mechanism for other components like Webrtc that interact with a remote Server. It interacts with the ApiServer to determine which other servers are supported, and map each Endpoint to an actual ApiCallback request. It provides an ApiContext for child components to quickly see if their server is supported and retrieve a fetch promise for each request. Learn more about customizing server interaction in the Client Developer Guide.

The Masher component sits atop the Editor interface, allowing editing of either a Cast or Mash. Context is provided to child components so they can access the underlying editor, call its methods, and display its content.

Higher level components like Player and Timeline logically organize particular functionality, in this case Mash display and Track editing. They both provide context for specific child components like PlayerButton and TimelineScrubber to operate within. For Cast display and Layer editing the Streamer and Composer components provide similiar functionality. The Browser and Inspector components provide a unified context for adding and altering content. Learn more about creating custom user interfaces in the Client Developer Guide.

theme-default

The theme-default NPM package has no runtime dependencies, but depends on react-icons during bundling. It packages icons into SVG content wrapped in JavaScript code, so this time consuming bundling step can be avoided in the client-react package. Learn more about creating custom user interfaces in the Styling Overview.