• Stars
    star
    306
  • Rank 136,456 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Record a video in the browser or directly on the File System from a canvas (2D/WebGL/WebGPU) as MP4, WebM, MKV, GIF, PNG/JPG Sequence using WebCodecs and Wasm when available.

canvas-record

npm version stability-stable npm minzipped size dependencies types Conventional Commits styled with prettier linted with eslint license

Record a video in the browser or directly on the File System from a canvas (2D/WebGL/WebGPU) as MP4, WebM, MKV, GIF, PNG/JPG Sequence using WebCodecs and Wasm when available.

paypal coinbase twitter

Installation

npm install canvas-record

Usage

import { Recorder, RecorderStatus, Encoders } from "canvas-record";
import createCanvasContext from "canvas-context";
import { AVC } from "media-codecs";

// Setup
const pixelRatio = devicePixelRatio;
const width = 512;
const height = 512;
const { context, canvas } = createCanvasContext("2d", {
  width: width * pixelRatio,
  height: height * pixelRatio,
  contextAttributes: { willReadFrequently: true },
});
Object.assign(canvas.style, { width: `${width}px`, height: `${height}px` });

const mainElement = document.querySelector("main");
mainElement.appendChild(canvas);

// Animation
let canvasRecorder;

function render() {
  const width = canvas.width;
  const height = canvas.height;

  const t = canvasRecorder.frame / canvasRecorder.frameTotal || Number.EPSILON;

  context.clearRect(0, 0, width, height);
  context.fillStyle = "red";
  context.fillRect(0, 0, t * width, height);
}

const tick = async () => {
  render();

  if (canvasRecorder.status !== RecorderStatus.Recording) return;
  await canvasRecorder.step();

  if (canvasRecorder.status !== RecorderStatus.Stopped) {
    requestAnimationFrame(() => tick());
  }
};

canvasRecorder = new Recorder(context, {
  name: "canvas-record-example",
  encoderOptions: {
    codec: AVC.getCodec({ profile: "Main", level: "5.2" }),
  },
});

// Start and encode frame 0
await canvasRecorder.start();

// Animate to encode the rest
tick(canvasRecorder);

API

Encoder comparison:

Encoder Extension Required Web API WASM Speed
WebCodecs mp4 / webm / mkv WebCodecs ❌ Fast
MP4Wasm mp4 WebCodecs βœ… (embed) Fast
H264MP4 mp4 βœ… (embed) Medium
FFmpeg mp4 / webm SharedArrayBuffer βœ… (need binary path) Slow
GIF gif WebWorkers (wip) ❌ Fast
Frame png / jpg File System Access ❌ Fast
MediaCapture mkv / webm MediaStream ❌ Realtime

Note:

  • WebCodecs encoderOptions allow different codecs to be used: VP8/VP9/AV1/HEVC. See media-codecs to get a codec string from human readable options and check which ones are supported in your browser with github.io/media-codecs.
  • WebCodecs 5-10x faster than H264MP4Encoder and 20x faster than FFmpeg (it needs to mux files after writing png to virtual FS)
  • FFmpeg (mp4 and webm) and WebCodecs (mp4) have a AVC maximum frame size of 9437184 pixels. That's fine until a bit more than 4K 16:9 @ 30fps. So if you need 4K Square or 8K exports, be patient with H264MP4Encoder (which probably also has the 4GB memory limit) or use Frame encoder and mux them manually with FFmpeg CLI (ffmpeg -framerate 30 -i "%05d.jpg" -b:v 60M -r 30 -profile:v baseline -pix_fmt yuv420p -movflags +faststart output.mp4)
  • MP4Wasm is embedded from mp4-wasm for ease of use (FFmpeg will require encoderOptions.corePath)

Roadmap:

  • add debug logging
  • use WebWorkers for gifenc

Modules

index

Re-export Recorder, RecorderStatus, all Encoders and utils.

Classes

Recorder

Base Recorder class.

Functions

onStatusChangeCb(RecorderStatus)

A callback to notify on the status change. To compare with RecorderStatus enum values.

Typedefs

RecorderOptions : object

Options for recording. All optional.

RecorderStartOptions : object

Options for recording. All optional.

index

Re-export Recorder, RecorderStatus, all Encoders and utils.

Recorder

Base Recorder class.

Kind: global class Properties

Name Type Default Description
[enabled] boolean true Enable/disable pointer interaction and drawing.

new Recorder(context, options)

Param Type
context RenderingContext
options RecorderOptions

recorder.start(startOptions)

Start the recording by initializing and optionally calling the initial step.

Kind: instance method of Recorder

Param Type
startOptions RecorderStartOptions

recorder.step()

Encode a frame and increment the time and the playhead. Calls await canvasRecorder.stop() when duration is reached.

Kind: instance method of Recorder

recorder.stop() β‡’ ArrayBuffer | Uint8Array | Array.<Blob> | undefined

Stop the recording and return the recorded buffer. If options.download is set, automatically start downloading the resulting file. Is called when duration is reached or manually.

Kind: instance method of Recorder

recorder.dispose()

Clean up

Kind: instance method of Recorder

RecorderStatus : enum

Enum for recorder status

Kind: global enum Read only: true Example

// Check recorder status before continuing
if (canvasRecorder.status !== RecorderStatus.Stopped) {
  rAFId = requestAnimationFrame(() => tick());
}

onStatusChangeCb(RecorderStatus)

A callback to notify on the status change. To compare with RecorderStatus enum values.

Kind: global function

Param Type Description
RecorderStatus number the status

RecorderOptions : object

Options for recording. All optional.

Kind: global typedef Properties

Name Type Default Description
[name] string "&quot;&quot;" A name for the recorder, used as prefix for the default file name.
[duration] number 10 The recording duration in seconds. If set to Infinity, await canvasRecorder.stop() needs to be called manually.
[frameRate] number 30 The frame rate in frame per seconds. Use await canvasRecorder.step(); to go to the next frame.
[download] boolean true Automatically download the recording when duration is reached or when await canvasRecorder.stop() is manually called.
[extension] boolean "mp4" Default file extension: infers which Encoder is selected.
[target] string "&quot;in-browser&quot;" Default writing target: in-browser or file-system when available.
[encoder] object A specific encoder. Default encoder based on options.extension: GIF > WebCodecs > H264MP4.
[encoderOptions] object See src/encoders or individual packages for a list of options.
[muxerOptions] object See "mp4-muxer" and "webm-muxer" for a list of options.
[onStatusChange] onStatusChangeCb

RecorderStartOptions : object

Options for recording. All optional.

Kind: global typedef Properties

Name Type Description
[filename] string Overwrite the file name completely.
[initOnly] boolean Only initialised the recorder and don't call the first await recorder.step().

License

All MIT:

MIT. See license file.

More Repositories

1

frontend-boilerplate

An ES20XX starter with common frontend tasks using Webpack 5 as module bundler and npm scripts as task runner.
JavaScript
227
star
2

dgel

A WebGPU engine.
TypeScript
186
star
3

glsl-tone-map

A collection of tone mapping functions available both as ES modules strings and as GLSL files for use with glslify.
GLSL
174
star
4

glsl-rotate

GLSL rotation functions with matrices: 2D and 3D (with X/Y/Z convenience functions) available both as ES modules strings and as GLSL files for use with glslify.
JavaScript
125
star
5

primitive-geometry

Geometries for 3D rendering, including normals, UVs and cell indices (faces). Perfect if you want to supercharge your dependency folder... with 30KB of geometries.
JavaScript
97
star
6

glsl-smaa

SMAA (Enhanced Subpixel Morphological Antialiasing) post-processing; WebGL (OpenGL ES 2.0) implementation with no fluff.
JavaScript
85
star
7

glsl-conditionals

Daniel Holden's functions designed to avoid conditionals in GLSL, available both as ES modules strings and as GLSL files for use with glslify.
GLSL
63
star
8

raf-perf

RAF loop with an adaptive fps and performance ratio calculated from either a sample count or a sample duration. Typically used when doing intensive graphics computation in canvas.
JavaScript
61
star
9

async-preloader

Assets preloader using async/await and fetch for usage both in the browser and Node.js.
JavaScript
61
star
10

sublime-stylefmt

Sublime Text plugin for Stylefmt
Python
49
star
11

vector-field

A data structure and lookup for 3D vector fields (flow fields).
JavaScript
40
star
12

frenet-serret-frames

Compute Frenet-Serret frames for a path of 3D points and tangents.
JavaScript
25
star
13

typedoc-material-theme

A TypeDoc theme based on Material 3.
CSS
23
star
14

media-codecs

Get a codec parameter string (like 'avc1.4d002a') from human readable options (like { name: 'Main', level: '4.2' }) and back to a descriptive name ('AVC Main Profile Level 4.2').
JavaScript
20
star
15

sass-easing

Easing variables for sass
CSS
19
star
16

cameras

Cameras for 3D rendering.
TypeScript
15
star
17

canvas-screenshot

A one trick pony package to download an image from a canvas.
JavaScript
14
star
18

bird-oid

A 3D boid system with accompanying emergent behaviors. Implementation mostly based on Craig Reynolds paper Steering Behaviors For Autonomous Characters.
JavaScript
13
star
19

canvas-context

Create a RenderingContext (2d, webgl, webgl2, bitmaprenderer, gpupresent), optionally offscreen for possible use in a Worker.
HTML
12
star
20

canvas-tint-image

A one trick pony package to tint an image with a canvas 2D context.
JavaScript
10
star
21

glsl-constants

Common GLSL math constants (with 11 decimals) available both as ES modules strings and as GLSL files for use with glslify.
GLSL
10
star
22

path-tangents

Compute tangents for a path of 3D points.
JavaScript
10
star
23

snowdev

Zero configuration, unbundled, opinionated development and prototyping server for simple ES modules development: types generation, format and linting, dev server and TypeScript support.
JavaScript
9
star
24

console-ansi

Easy console coloring and prefixing via Proxy object with ANSI strings.
JavaScript
8
star
25

prtt

A WebGL prototype starter using webpack, redux, babel, glslify, controlkit, ccapture
JavaScript
6
star
26

perspective-grid

Two point perspective grid on canvas
JavaScript
6
star
27

jest-environment-jsdom-latest

Jest environment to use the latest jsdom API and features
JavaScript
5
star
28

typed-array-concat

Concatenate n typed arrays
JavaScript
5
star
29

react-redux-workshop

An introductory workshop featuring React, Redux, react-router, i18next, gsap and createjs.
JavaScript
4
star
30

canvas-thumbnail-cache

Draw images into a canvas square grid for fast retrieval at a thumbnail size.
JavaScript
3
star
31

less-easing

Easing variables for less
CSS
3
star
32

sass-font-face

Font-face mixin for sass
CSS
3
star
33

es-modules-in-the-browser-almost-now

HTML
3
star
34

parallaxjs

Parallax. Parallax. Parallax. Pa. Ra. LLax.
JavaScript
3
star
35

eerp

Logarithmic/exponential interpolation.
JavaScript
3
star
36

rollup-plugin-commonjs-named-exports

Re-export CommonJS named exports using Node.js cjs-module-lexer.
JavaScript
3
star
37

hot-red

Experiment about The Getaway album by the Red Hot Chili Peppers
HTML
2
star
38

primitive-ellipsoid

An ellipsoid geometry for 3D rendering, including normals, UVs and cell indices (faces).
JavaScript
2
star
39

alfred-xampp-workflow

XAMPP commands
2
star
40

styl-easing

Easing variables for stylus
CSS
2
star
41

css-easing

Easing variables for css
CSS
2
star
42

airports-data

Airports data: static, dynamic and custom dump.
JavaScript
2
star
43

gulp-json-stylus

Gulp plugin that converts JSON files into stylus variables.
JavaScript
2
star
44

event-utils

An event utils system written in ES6.
JavaScript
2
star
45

adaptable-text

Adapt font size to a specified width.
JavaScript
2
star
46

typed-array-constructor

Get a typed array constructor based on the hypothetical max value it could contain. Signed or unsigned.
JavaScript
2
star
47

vscode-wavefront

Grammars for Wavefront .obj and .mtl files.
1
star
48

require-backbone-marionette-handlebars

Complete Alex Sexton's Require.js Handlebars Plugin to work with Marionette. Provide a simple render logic.
1
star
49

sublime-sketchjs

Completions and snippets for Sketch.js.
JavaScript
1
star
50

codevember-2017

One experiment a day keeps the doctor away.
HTML
1
star
51

auto-reload-page

Auto reload a page at a specified interval.
JavaScript
1
star
52

experiment-dispersed

JavaScript
1
star
53

bayer

Compute the bayer matrix based for powers of two. Useful for ordered dithering algorithms.
HTML
1
star
54

rollup-plugin-no-op

Replace imported module with 'export default {}' using module IDs. Useful when using 'external' is not enough.
JavaScript
1
star
55

parse-exr

EXR file parser. Ported from Three.js implementation without depending on it.
JavaScript
1
star
56

typed-array-interleave

Interleave n typed arrays.
JavaScript
1
star
57

styl-font-face

Font-face mixin for stylus
CSS
1
star
58

less-font-face

Font-face mixin for less
CSS
1
star
59

convert-assets-webpack-plugin

Convert compiled files buffer loaded by webpack using any package and choosing their output location.
JavaScript
1
star
60

canvas-pattern

Draw and cache a repeated pattern on a canvas context.
JavaScript
1
star
61

gel

1
star
62

tealc

isEqual in Jaffa. Return 'indeed' if equal.
JavaScript
1
star
63

maxwell-triangle

Get color values inside a Maxwell triangle from positions and vice versa.
JavaScript
1
star
64

web-mime-types

Mapping of the most common MIME types on the Web by extension. Currently 75 extensions.
JavaScript
1
star