Skip to content

shotstack/shotstack-studio-sdk

Repository files navigation

Shotstack Studio

npm version License TypeScript

A JavaScript library for creating and editing videos in the browser.

Interactive Examples

Try Shotstack Studio in your preferred framework:

TypeScript React Vue Angular Next.js

Features

  • Create video compositions with multiple tracks and clips
  • Visual timeline interface
  • WYSIWYG text editing
  • Multi-track, drag-and-drop clip manipulation with snap-to-grid
  • Use in conjunction with the Shotstack Edit API to render video
  • Export to video using browser-based FFmpeg

Installation

npm install @shotstack/shotstack-studio
yarn add @shotstack/shotstack-studio

FFmpeg (peer dependency)

Install FFmpeg to use the browser based VideoExporter class. This is kept separate to prevent WASM / Web Worker clashes in frameworks like Next.js.

npm install @ffmpeg/ffmpeg

You can skip this if you're using the Shotstack Edit API for rendering videos.

Quick Start

import { Edit, Canvas, Controls, Timeline } from "@shotstack/shotstack-studio";

// 1. Load a template
const response = await fetch("https://shotstack-assets.s3.amazonaws.com/templates/hello-world/hello.json");
const template = await response.json();

// 2. Initialize the edit
const edit = new Edit(template.output.size, template.timeline.background);
await edit.load();

// 3. Create a canvas to display the edit
const canvas = new Canvas(template.output.size, edit);
await canvas.load(); // Renders to [data-shotstack-studio] element

// 4. Load the template
await edit.loadEdit(template);

// 5. Initialize the Timeline
const timeline = new Timeline(edit, { width: 1280, height: 300 });
await timeline.load(); // Renders to [data-shotstack-timeline] element

// 6. Add keyboard controls
const controls = new Controls(edit);
await controls.load();

Your HTML should include containers for both the canvas and timeline:

<div data-shotstack-studio></div>
<div data-shotstack-timeline></div>

Main Components

Edit

The Edit class represents a video project with its timeline, clips, and properties.

// Create an edit with dimensions and background
const edit = new Edit({ width: 1280, height: 720 }, "#000000");
await edit.load();

// Load from template
await edit.loadEdit(templateJson);

// Playback controls
edit.play();
edit.pause();
edit.seek(2000); // Seek to 2 seconds (in milliseconds)
edit.stop(); // Stop and return to beginning

// Editing functions
edit.addClip(0, {
	asset: {
		type: "image",
		src: "https://example.com/image.jpg"
	},
	start: 0,
	length: 5
});

edit.addTrack(1, { clips: [] });
edit.deleteClip(0, 0);
edit.deleteTrack(1);

// Undo/Redo
edit.undo();
edit.redo();

// Get edit information
const clip = edit.getClip(0, 0);
const track = edit.getTrack(0);
const editJson = edit.getEdit();
const duration = edit.totalDuration; // in milliseconds

Events

The Edit class provides an event system to listen for specific actions:

// Listen for clip selection events
edit.events.on("clip:selected", data => {
	console.log("Clip selected:", data.clip);
	console.log("Track index:", data.trackIndex);
	console.log("Clip index:", data.clipIndex);
});

// Listen for clip update events
edit.events.on("clip:updated", data => {
	console.log("Previous state:", data.previous); // { clip, trackIndex, clipIndex }
	console.log("Current state:", data.current); // { clip, trackIndex, clipIndex }
});

Available events:

  • clip:selected - Emitted when a clip is initially selected, providing data about the clip, its track index, and clip index.
  • clip:updated - Emitted when a clip's properties are modified, providing both previous and current states.

Canvas

The Canvas class provides the visual rendering of the edit.

// Create and load the canvas
const canvas = new Canvas(edit.size, edit);
await canvas.load();

// Zoom and positioning
canvas.centerEdit();
canvas.zoomToFit();
canvas.setZoom(1.5); // 1.0 is 100%, 0.5 is 50%, etc.
canvas.dispose(); // Clean up resources when done

Controls

The Controls class adds keyboard controls for playback.

const controls = new Controls(edit);
await controls.load();

// Available keyboard controls:
// Space - Play/Pause
// J - Stop
// K - Pause
// L - Play
// Left Arrow - Seek backward
// Right Arrow - Seek forward
// Shift + Arrow - Seek larger amount
// Comma - Step backward one frame
// Period - Step forward one frame
// Cmd/Ctrl + Z - Undo
// Cmd/Ctrl + Shift + Z - Redo

Timeline

The Timeline class provides a visual timeline interface for editing.

import { Timeline } from "@shotstack/shotstack-studio";

const timeline = new Timeline(edit, { width: 1280, height: 300 });
await timeline.load();

// Timeline features:
// - Visual track and clip representation
// - Drag-and-drop clip manipulation
// - Clip resizing with edge detection
// - Playhead control for navigation
// - Snap-to-grid functionality
// - Zoom and scroll controls

VideoExporter

The VideoExporter class exports the edit to a video file.

const exporter = new VideoExporter(edit, canvas);
await exporter.export("my-video.mp4", 25); // filename, fps

Theming

Shotstack Studio supports theming for visual components. Currently, theming is available for the Timeline component, with Canvas theming coming in a future releases.

Built-in Themes

The library includes pre-designed themes that you can use immediately:

import { Timeline } from "@shotstack/shotstack-studio";
import darkTheme from "@shotstack/shotstack-studio/themes/dark.json";
import minimalTheme from "@shotstack/shotstack-studio/themes/minimal.json";

// Apply a theme when creating the timeline
const timeline = new Timeline(edit, { width: 1280, height: 300 }, { theme: darkTheme });

Custom Themes

Create your own theme by defining colors and dimensions for each component:

const customTheme = {
	timeline: {
		// Main timeline colors
		background: "#1e1e1e",
		divider: "#1a1a1a",
		playhead: "#ff4444",
		snapGuide: "#888888",
		dropZone: "#00ff00",
		trackInsertion: "#00ff00",

		// Toolbar styling
		toolbar: {
			background: "#1a1a1a",
			surface: "#2a2a2a", // Button backgrounds
			hover: "#3a3a3a", // Button hover state
			active: "#007acc", // Button active state
			divider: "#3a3a3a", // Separator lines
			icon: "#888888", // Icon colors
			text: "#ffffff", // Text color
			height: 36 // Toolbar height in pixels
		},

		// Ruler styling
		ruler: {
			background: "#404040",
			text: "#ffffff", // Time labels
			markers: "#666666", // Time marker dots
			height: 40 // Ruler height in pixels
		},

		// Track styling
		tracks: {
			surface: "#2d2d2d", // Primary track color
			surfaceAlt: "#252525", // Alternating track color
			border: "#3a3a3a", // Track borders
			height: 60 // Track height in pixels
		},

		// Clip colors by asset type
		clips: {
			video: "#4a9eff",
			audio: "#00d4aa",
			image: "#f5a623",
			text: "#d0021b",
			shape: "#9013fe",
			html: "#50e3c2",
			luma: "#b8e986",
			default: "#8e8e93", // Unknown asset types
			selected: "#007acc", // Selection border
			radius: 4 // Corner radius in pixels
		}
	}
	// Canvas theming will be available in future releases
	// canvas: { ... }
};

const timeline = new Timeline(edit, { width: 1280, height: 300 }, { theme: customTheme });

Theme Structure

Themes are organized by component, making it intuitive to customize specific parts of the interface:

  • Timeline: Controls the appearance of the timeline interface

    • toolbar: Playback controls and buttons
    • ruler: Time markers and labels
    • tracks: Track backgrounds and borders
    • clips: Asset-specific colors and selection states
    • Global timeline properties (background, playhead, etc.)
  • Canvas (coming soon): Will control the appearance of the video preview area

Template Format

Templates use a JSON format with the following structure:

{
  timeline: {
    background: "#000000",
    fonts: [
      { src: "https://example.com/font.ttf" }
    ],
    tracks: [
      {
        clips: [
          {
            asset: {
              type: "image", // image, video, text, shape, audio
              src: "https://example.com/image.jpg",
              // Other asset properties depend on type
            },
            start: 0,        // Start time in seconds
            length: 5,       // Duration in seconds
            transition: {    // Optional transitions
              in: "fade",
              out: "fade"
            },
            position: "center", // Positioning
            scale: 1,           // Scale factor
			offset: {
				x: 0.1,         // X-axis offset relative to position
				y: 0            // Y-axis offset relative to position
			}
          }
        ]
      }
    ]
  },
  output: {
    format: "mp4",
    size: {
      width: 1280,
      height: 720
    }
  }
}

License

PolyForm Shield License 1.0.0

API Reference

Edit

The Edit class represents a video editing project with its timeline, clips, and properties.

import { Edit } from "@shotstack/shotstack-studio";
import { EditSchema } from "@shotstack/shotstack-studio";

Constructor

constructor(size: Size, backgroundColor: string = "#ffffff")

Creates a new Edit instance with the specified dimensions and background color.

Properties

  • assetLoader - Asset loader instance for managing media assets
  • events - Event emitter for handling events
  • playbackTime - Current playback position in milliseconds
  • totalDuration - Total duration of the edit in milliseconds

Methods

  • async load() - Initialize and prepare the edit for rendering
  • async loadEdit(edit: EditType) - Load an edit from a JSON template
  • play() - Start playback
  • pause() - Pause playback
  • seek(target: number) - Seek to a specific time in milliseconds
  • stop() - Stop playback and return to beginning
  • addClip(trackIdx: number, clip: ClipType) - Add a clip to a specific track
  • deleteClip(trackIdx: number, clipIdx: number) - Delete a clip
  • getClip(trackIdx: number, clipIdx: number) - Get a clip by track and index
  • addTrack(trackIdx: number, track: TrackType) - Add a new track
  • getTrack(trackIdx: number) - Get a track by index
  • deleteTrack(trackIdx: number) - Delete a track
  • getEdit() - Get the full edit configuration as a JSON object
  • undo() - Undo the last editing operation
  • redo() - Redo the last undone operation

Events

  • clip:selected - Triggered when a clip is selected
  • clip:updated - Triggered when a clip is modified
  • edit:undo - Triggered when an undo operation is performed
  • edit:redo - Triggered when a redo operation is performed

Canvas

The Canvas class provides the visual rendering of the edit.

import { Canvas } from "@shotstack/shotstack-studio";
import type { Size } from "@shotstack/shotstack-studio";

Constructor

constructor(size: Size, edit: Edit)

Creates a new canvas with specified dimensions for rendering the edit.

Methods

  • async load() - Initialize the canvas and add it to the DOM
  • centerEdit() - Center the edit in the canvas
  • zoomToFit() - Zoom to fit the entire edit
  • setZoom(zoom: number) - Set zoom level
  • dispose() - Clean up resources and remove the canvas from the DOM

Controls

The Controls class adds keyboard controls for playback.

import { Controls } from "@shotstack/shotstack-studio";

Constructor

constructor(edit: Edit)

Creates a new controls instance for the provided Edit.

Methods

  • async load() - Set up event listeners for keyboard controls

Timeline

The Timeline class provides a visual timeline interface for video editing.

import { Timeline } from "@shotstack/shotstack-studio";

Constructor

constructor(edit: Edit, size: { width: number, height: number }, themeOptions?: TimelineThemeOptions)

Creates a new timeline interface for the provided Edit.

Methods

  • async load() - Initialize the timeline and add it to the DOM
  • setTheme(themeOptions: TimelineThemeOptions) - Change the timeline theme
  • setOptions(options: Partial<TimelineOptions>) - Update timeline options
  • dispose() - Clean up resources and remove from DOM

VideoExporter

The VideoExporter class handles exporting the edit to mp4.

import { VideoExporter } from "@shotstack/shotstack-studio";

Constructor

constructor(edit: Edit, canvas: Canvas)

Creates a new exporter for the provided Edit and Canvas.

Methods

  • async export(filename: string = "shotstack-export.mp4", fps: number = 25) - Export the edit to a video file

About

A JavaScript library for creating and editing videos in the browser.

Resources

License

Stars

Watchers

Forks

Languages