Socket
Socket
Sign inDemoInstall

canvas-record

Package Overview
Dependencies
14
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.2.0 to 5.0.0-beta.0

snowdev.config.js

27

CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
# [5.0.0-beta.0](https://github.com/dmnsgn/canvas-record/compare/v4.2.0...v5.0.0-beta.0) (2023-11-04)
### Bug Fixes
* correct RecorderOptions extension type ([084a155](https://github.com/dmnsgn/canvas-record/commit/084a155f515fcff5a27b0cde73fdef40a173b96d)), closes [#12](https://github.com/dmnsgn/canvas-record/issues/12)
* framerate spelling is not following camelcase in VideoEncoder config ([f9c2662](https://github.com/dmnsgn/canvas-record/commit/f9c2662aced88880e40bff8c8ea0b690938b3235))
### Build System
* update dependencies ([66defa1](https://github.com/dmnsgn/canvas-record/commit/66defa1d1ba1acb8428f10ab4d43f556bf538b23))
### Features
* educated guess for bitrate from resolution and framerate ([acb38c5](https://github.com/dmnsgn/canvas-record/commit/acb38c56994a76263c3a66e714763ea96ef3a050)), closes [#13](https://github.com/dmnsgn/canvas-record/issues/13)
### BREAKING CHANGES
* ffmpeg has different binaries and likely to break
# [4.2.0](https://github.com/dmnsgn/canvas-record/compare/v4.1.0...v4.2.0) (2023-05-20)

@@ -6,0 +31,0 @@

2

index.js
/**
* Re-export Recorder, RecorderStatus, all Encoders and utils.
* @module index
* @module canvas-record
*/

@@ -5,0 +5,0 @@

{
"name": "canvas-record",
"version": "4.2.0",
"version": "5.0.0-beta.0",
"description": "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.",

@@ -47,3 +47,4 @@ "keywords": [

"dependencies": {
"@ffmpeg/ffmpeg": "^0.11.6",
"@ffmpeg/ffmpeg": "^0.12.7",
"@ffmpeg/util": "^0.12.1",
"canvas-screenshot": "^4.1.0",

@@ -53,18 +54,21 @@ "gifenc": "^1.0.3",

"media-codecs": "^2.0.0",
"mp4-muxer": "^2.1.1",
"webm-muxer": "^3.1.0"
"mp4-muxer": "^3.0.0",
"webm-muxer": "^3.1.3"
},
"devDependencies": {
"@web/rollup-plugin-import-meta-assets": "^2.1.0",
"canvas-context": "^3.2.0",
"es-module-shims": "^1.7.2",
"es-module-shims": "^1.8.1",
"mp4-wasm": "^1.0.6",
"tweakpane": "^3.1.9"
"rollup": "^4.1.5",
"tweakpane": "^4.0.1"
},
"optionalDependencies": {
"@ffmpeg/core": "^0.12.3",
"@ffmpeg/core-mt": "^0.12.3"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"snowdev": {
"crossOriginIsolation": true
}
}

@@ -118,3 +118,3 @@ # canvas-record

<dl>
<dt><a href="#module_index">index</a></dt>
<dt><a href="#module_canvas-record">canvas-record</a></dt>
<dd><p>Re-export Recorder, RecorderStatus, all Encoders and utils.</p>

@@ -128,3 +128,26 @@ </dd>

<dt><a href="#Recorder">Recorder</a></dt>
<dd><p>Base Recorder class.</p>
<dd></dd>
<dt><a href="#Encoder">Encoder</a></dt>
<dd></dd>
<dt><a href="#FFmpegEncoder">FFmpegEncoder</a></dt>
<dd></dd>
<dt><a href="#FrameEncoder">FrameEncoder</a></dt>
<dd></dd>
<dt><a href="#GIFEncoder">GIFEncoder</a></dt>
<dd></dd>
<dt><a href="#H264MP4Encoder">H264MP4Encoder</a></dt>
<dd></dd>
<dt><a href="#MP4WasmEncoder">MP4WasmEncoder</a></dt>
<dd></dd>
<dt><a href="#MediaCaptureEncoder">MediaCaptureEncoder</a></dt>
<dd></dd>
<dt><a href="#WebCodecsEncoder">WebCodecsEncoder</a></dt>
<dd></dd>
</dl>
## Constants
<dl>
<dt><a href="#isWebCodecsSupported">isWebCodecsSupported</a> : <code>boolean</code></dt>
<dd><p>Check for WebCodecs support on the current platform.</p>
</dd>

@@ -136,4 +159,5 @@ </dl>

<dl>
<dt><a href="#onStatusChangeCb">onStatusChangeCb(RecorderStatus)</a></dt>
<dd><p>A callback to notify on the status change. To compare with RecorderStatus enum values.</p>
<dt><a href="#estimateBitRate">estimateBitRate(width, height, frameRate, motionRank, bitrateMode)</a> ⇒ <code>number</code></dt>
<dd><p>Estimate the bit rate of a video rounded to nearest megabit.
Based on &quot;H.264 for the rest of us&quot; by Kush Amerasinghe.</p>
</dd>

@@ -145,2 +169,5 @@ </dl>

<dl>
<dt><a href="#onStatusChangeCb">onStatusChangeCb</a> : <code>function</code></dt>
<dd><p>A callback to notify on the status change. To compare with RecorderStatus enum values.</p>
</dd>
<dt><a href="#RecorderOptions">RecorderOptions</a> : <code>object</code></dt>

@@ -150,9 +177,41 @@ <dd><p>Options for recording. All optional.</p>

<dt><a href="#RecorderStartOptions">RecorderStartOptions</a> : <code>object</code></dt>
<dd><p>Options for recording. All optional.</p>
<dd><p>Options for recording initialisation. All optional.</p>
</dd>
<dt><a href="#EncoderExtensions">EncoderExtensions</a> : <code>&quot;mp4&quot;</code> | <code>&quot;webm&quot;</code> | <code>&quot;png&quot;</code> | <code>&quot;jpg&quot;</code> | <code>&quot;gif&quot;</code> | <code>&quot;mkv&quot;</code></dt>
<dd></dd>
<dt><a href="#EncoderTarget">EncoderTarget</a> : <code>&quot;in-browser&quot;</code> | <code>&quot;file-system&quot;</code></dt>
<dd></dd>
<dt><a href="#FFmpegEncoderOptions">FFmpegEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#FFmpegEncoderEncoderOptions">FFmpegEncoderEncoderOptions</a> : <code>module:@ffmpeg/ffmpeg/dist/esm/types.js~FFMessageLoadConfig</code></dt>
<dd></dd>
<dt><a href="#GIFEncoderOptions">GIFEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#GIFEncoderQuantizeOptions">GIFEncoderQuantizeOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#GIFEncoderEncoderOptions">GIFEncoderEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#H264MP4EncoderOptions">H264MP4EncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#H264MP4EncoderEncoderOptions">H264MP4EncoderEncoderOptions</a> : <code>module:h264-mp4-encoder~H264MP4Encoder</code></dt>
<dd></dd>
<dt><a href="#MP4WasmEncoderOptions">MP4WasmEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#MP4WasmEncoderEncoderOptions">MP4WasmEncoderEncoderOptions</a> : <code>VideoEncoderConfig</code></dt>
<dd></dd>
<dt><a href="#MediaCaptureEncoderOptions">MediaCaptureEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#MediaCaptureEncoderEncoderOptions">MediaCaptureEncoderEncoderOptions</a> : <code>MediaRecorderOptions</code></dt>
<dd></dd>
<dt><a href="#WebCodecsEncoderOptions">WebCodecsEncoderOptions</a> : <code>object</code></dt>
<dd></dd>
<dt><a href="#WebCodecsEncoderEncoderOptions">WebCodecsEncoderEncoderOptions</a> : <code>VideoEncoderConfig</code></dt>
<dd></dd>
<dt><a href="#WebCodecsMuxerOptions">WebCodecsMuxerOptions</a> : <code>MuxerOptions</code></dt>
<dd></dd>
</dl>
<a name="module_index"></a>
<a name="module_canvas-record"></a>
## index
## canvas-record

@@ -165,14 +224,9 @@ Re-export Recorder, RecorderStatus, all Encoders and utils.

Base Recorder class.
**Kind**: global class
**Properties**
| Name | Type | Default | Description |
| --------- | -------------------- | ----------------- | ----------------------------------------------- |
| [enabled] | <code>boolean</code> | <code>true</code> | Enable/disable pointer interaction and drawing. |
- [Recorder](#Recorder)
- [new Recorder(context, options)](#new_Recorder_new)
- [.start(startOptions)](#Recorder+start)
- [new Recorder(context, [options])](#new_Recorder_new)
- [.defaultOptions](#Recorder+defaultOptions) : [<code>RecorderOptions</code>](#RecorderOptions)
- [.mimeTypes](#Recorder+mimeTypes) : <code>object</code>
- [.start([startOptions])](#Recorder+start)
- [.step()](#Recorder+step)

@@ -184,12 +238,28 @@ - [.stop()](#Recorder+stop) ⇒ <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Array.&lt;Blob&gt;</code> \| <code>undefined</code>

### new Recorder(context, options)
### new Recorder(context, [options])
| Param | Type |
| ------- | ------------------------------------------------ |
| context | <code>RenderingContext</code> |
| options | [<code>RecorderOptions</code>](#RecorderOptions) |
Create a Recorder instance
| Param | Type | Default |
| --------- | ------------------------------------------------ | --------------- |
| context | <code>RenderingContext</code> | |
| [options] | [<code>RecorderOptions</code>](#RecorderOptions) | <code>{}</code> |
<a name="Recorder+defaultOptions"></a>
### recorder.defaultOptions : [<code>RecorderOptions</code>](#RecorderOptions)
Sensible defaults for recording so that the recorder "just works".
**Kind**: instance property of [<code>Recorder</code>](#Recorder)
<a name="Recorder+mimeTypes"></a>
### recorder.mimeTypes : <code>object</code>
A mapping of extension to their mime types
**Kind**: instance property of [<code>Recorder</code>](#Recorder)
<a name="Recorder+start"></a>
### recorder.start(startOptions)
### recorder.start([startOptions])

@@ -200,5 +270,5 @@ Start the recording by initializing and optionally calling the initial step.

| Param | Type |
| ------------ | ---------------------------------------------------------- |
| startOptions | [<code>RecorderStartOptions</code>](#RecorderStartOptions) |
| Param | Type | Default |
| -------------- | ---------------------------------------------------------- | --------------- |
| [startOptions] | [<code>RecorderStartOptions</code>](#RecorderStartOptions) | <code>{}</code> |

@@ -226,5 +296,174 @@ <a name="Recorder+step"></a>

Clean up
Clean up the recorder and encoder
**Kind**: instance method of [<code>Recorder</code>](#Recorder)
<a name="Encoder"></a>
## Encoder
**Kind**: global class
**Properties**
| Name | Type |
| ---------------- | ---------------------------------------------------- |
| target | [<code>EncoderTarget</code>](#EncoderTarget) |
| extension | [<code>EncoderExtensions</code>](#EncoderExtensions) |
| [encoderOptions] | <code>object</code> |
| [muxerOptions] | <code>object</code> |
- [Encoder](#Encoder)
- [new Encoder(options)](#new_Encoder_new)
- [.supportedExtensions](#Encoder+supportedExtensions) : <code>Array.&lt;Extensions&gt;</code>
- [.supportedTargets](#Encoder+supportedTargets) : [<code>Array.&lt;EncoderTarget&gt;</code>](#EncoderTarget)
- [.init(options)](#Encoder+init)
- [.encode(frame, [frameNumber])](#Encoder+encode)
- [.stop()](#Encoder+stop) ⇒ <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Array.&lt;Blob&gt;</code> \| <code>undefined</code>
- [.dispose()](#Encoder+dispose)
<a name="new_Encoder_new"></a>
### new Encoder(options)
Base Encoder class. All Encoders extend it and its method are called by the Recorder.
| Param | Type |
| ------- | ------------------- |
| options | <code>object</code> |
<a name="Encoder+supportedExtensions"></a>
### encoder.supportedExtensions : <code>Array.&lt;Extensions&gt;</code>
The extension the encoder supports
**Kind**: instance property of [<code>Encoder</code>](#Encoder)
<a name="Encoder+supportedTargets"></a>
### encoder.supportedTargets : [<code>Array.&lt;EncoderTarget&gt;</code>](#EncoderTarget)
The target to download the file to.
**Kind**: instance property of [<code>Encoder</code>](#Encoder)
<a name="Encoder+init"></a>
### encoder.init(options)
Setup the encoder: load binary, instantiate muxers, setup file system target...
**Kind**: instance method of [<code>Encoder</code>](#Encoder)
| Param | Type |
| ------- | ------------------- |
| options | <code>object</code> |
<a name="Encoder+encode"></a>
### encoder.encode(frame, [frameNumber])
Encode a single frame. The frameNumber is usually used for GOP (Group Of Pictures).
**Kind**: instance method of [<code>Encoder</code>](#Encoder)
| Param | Type |
| ------------- | ------------------- |
| frame | <code>number</code> |
| [frameNumber] | <code>number</code> |
<a name="Encoder+stop"></a>
### encoder.stop() ⇒ <code>ArrayBuffer</code> \| <code>Uint8Array</code> \| <code>Array.&lt;Blob&gt;</code> \| <code>undefined</code>
Stop the encoding process and cleanup the temporary data.
**Kind**: instance method of [<code>Encoder</code>](#Encoder)
<a name="Encoder+dispose"></a>
### encoder.dispose()
Clean up the encoder
**Kind**: instance method of [<code>Encoder</code>](#Encoder)
<a name="FFmpegEncoder"></a>
## FFmpegEncoder
**Kind**: global class
<a name="new_FFmpegEncoder_new"></a>
### new FFmpegEncoder([options])
| Param | Type |
| --------- | ---------------------------------------------------------- |
| [options] | [<code>FFmpegEncoderOptions</code>](#FFmpegEncoderOptions) |
<a name="FrameEncoder"></a>
## FrameEncoder
**Kind**: global class
<a name="GIFEncoder"></a>
## GIFEncoder
**Kind**: global class
<a name="new_GIFEncoder_new"></a>
### new GIFEncoder([options])
| Param | Type |
| --------- | ---------------------------------------------------- |
| [options] | [<code>GIFEncoderOptions</code>](#GIFEncoderOptions) |
<a name="H264MP4Encoder"></a>
## H264MP4Encoder
**Kind**: global class
<a name="new_H264MP4Encoder_new"></a>
### new H264MP4Encoder([options])
| Param | Type |
| --------- | ------------------------------------------------------------ |
| [options] | [<code>H264MP4EncoderOptions</code>](#H264MP4EncoderOptions) |
<a name="MP4WasmEncoder"></a>
## MP4WasmEncoder
**Kind**: global class
<a name="new_MP4WasmEncoder_new"></a>
### new MP4WasmEncoder([options])
| Param | Type |
| --------- | ------------------------------------------------------------ |
| [options] | [<code>MP4WasmEncoderOptions</code>](#MP4WasmEncoderOptions) |
<a name="MediaCaptureEncoder"></a>
## MediaCaptureEncoder
**Kind**: global class
<a name="new_MediaCaptureEncoder_new"></a>
### new MediaCaptureEncoder([options])
| Param | Type |
| --------- | ---------------------------------------------------------------------- |
| [options] | [<code>MediaCaptureEncoderOptions</code>](#MediaCaptureEncoderOptions) |
<a name="WebCodecsEncoder"></a>
## WebCodecsEncoder
**Kind**: global class
<a name="new_WebCodecsEncoder_new"></a>
### new WebCodecsEncoder([options])
| Param | Type |
| --------- | ---------------------------------------------------------------- |
| [options] | [<code>WebCodecsEncoderOptions</code>](#WebCodecsEncoderOptions) |
<a name="RecorderStatus"></a>

@@ -247,9 +486,42 @@

<a name="isWebCodecsSupported"></a>
## isWebCodecsSupported : <code>boolean</code>
Check for WebCodecs support on the current platform.
**Kind**: global constant
<a name="estimateBitRate"></a>
## estimateBitRate(width, height, frameRate, motionRank, bitrateMode) ⇒ <code>number</code>
Estimate the bit rate of a video rounded to nearest megabit.
Based on "H.264 for the rest of us" by Kush Amerasinghe.
**Kind**: global function
**Returns**: <code>number</code> - A bitrate value in bits per second
| Param | Type | Default | Description |
| ----------- | ---------------------------------------------------------------------- | --------------------- | --------------------- |
| width | <code>number</code> | | |
| height | <code>number</code> | | |
| frameRate | <code>number</code> | <code>30</code> | |
| motionRank | <code>number</code> | <code>4</code> | A factor of 1, 2 or 4 |
| bitrateMode | <code>&quot;variable&quot;</code> \| <code>&quot;constant&quot;</code> | <code>variable</code> | |
**Example**
```js
// Full HD (1080p)
const bitRate = estimateBitRate(1920, 1080, 30, "variable");
const bitRateMbps = bitRate * 1_000_000; // => 13 Mbps
```
<a name="onStatusChangeCb"></a>
## onStatusChangeCb(RecorderStatus)
## onStatusChangeCb : <code>function</code>
A callback to notify on the status change. To compare with RecorderStatus enum values.
**Kind**: global function
**Kind**: global typedef

@@ -275,3 +547,3 @@ | Param | Type | Description |

| [download] | <code>boolean</code> | <code>true</code> | Automatically download the recording when duration is reached or when `await canvasRecorder.stop()` is manually called. |
| [extension] | <code>boolean</code> | <code>&quot;mp4&quot;</code> | Default file extension: infers which Encoder is selected. |
| [extension] | <code>string</code> | <code>&quot;\&quot;mp4\&quot;&quot;</code> | Default file extension: infers which Encoder is selected. |
| [target] | <code>string</code> | <code>&quot;\&quot;in-browser\&quot;&quot;</code> | Default writing target: in-browser or file-system when available. |

@@ -287,3 +559,3 @@ | [encoder] | <code>object</code> | | A specific encoder. Default encoder based on options.extension: GIF > WebCodecs > H264MP4. |

Options for recording. All optional.
Options for recording initialisation. All optional.

@@ -298,2 +570,160 @@ **Kind**: global typedef

<a name="EncoderExtensions"></a>
## EncoderExtensions : <code>&quot;mp4&quot;</code> \| <code>&quot;webm&quot;</code> \| <code>&quot;png&quot;</code> \| <code>&quot;jpg&quot;</code> \| <code>&quot;gif&quot;</code> \| <code>&quot;mkv&quot;</code>
**Kind**: global typedef
<a name="EncoderTarget"></a>
## EncoderTarget : <code>&quot;in-browser&quot;</code> \| <code>&quot;file-system&quot;</code>
**Kind**: global typedef
<a name="FFmpegEncoderOptions"></a>
## FFmpegEncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ---------------- | ------------------------------------------------------------------------ | --------------- |
| [encoderOptions] | [<code>FFmpegEncoderEncoderOptions</code>](#FFmpegEncoderEncoderOptions) | <code>{}</code> |
<a name="FFmpegEncoderEncoderOptions"></a>
## FFmpegEncoderEncoderOptions : <code>module:@ffmpeg/ffmpeg/dist/esm/types.js~FFMessageLoadConfig</code>
**Kind**: global typedef
**See**: [FFmpeg#load](https://ffmpegwasm.netlify.app/docs/api/ffmpeg/classes/FFmpeg#load)
<a name="GIFEncoderOptions"></a>
## GIFEncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ----------------- | -------------------------------------------------------------------- | ---------------- |
| [maxColors] | <code>number</code> | <code>256</code> |
| [quantizeOptions] | [<code>GIFEncoderQuantizeOptions</code>](#GIFEncoderQuantizeOptions) | |
| [encoderOptions] | [<code>GIFEncoderEncoderOptions</code>](#GIFEncoderEncoderOptions) | <code>{}</code> |
<a name="GIFEncoderQuantizeOptions"></a>
## GIFEncoderQuantizeOptions : <code>object</code>
**Kind**: global typedef
**See**: [QuantizeOptions](https://github.com/mattdesl/gifenc#palette--quantizergba-maxcolors-options--)
**Properties**
| Name | Type | Default |
| --------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------- |
| [format] | <code>&quot;rgb565&quot;</code> \| <code>&quot;rgb444&quot;</code> \| <code>&quot;rgba4444&quot;</code> | <code>&quot;rgb565&quot;</code> |
| [oneBitAlpha] | <code>boolean</code> \| <code>number</code> | <code>false</code> |
| [clearAlpha] | <code>boolean</code> | <code>true</code> |
| [clearAlphaThreshold] | <code>number</code> | <code>0</code> |
| [clearAlphaColor] | <code>number</code> | <code>0x00</code> |
<a name="GIFEncoderEncoderOptions"></a>
## GIFEncoderEncoderOptions : <code>object</code>
**Kind**: global typedef
**See**: [WriteFrameOpts](https://github.com/mattdesl/gifenc#gifwriteframeindex-width-height-opts--)
**Properties**
| Name | Type | Default |
| ------------------ | ----------------------------------------------- | ------------------ |
| [palette] | <code>Array.&lt;Array.&lt;number&gt;&gt;</code> | |
| [first] | <code>boolean</code> | <code>false</code> |
| [transparent] | <code>boolean</code> | <code>0</code> |
| [transparentIndex] | <code>number</code> | <code>0</code> |
| [delay] | <code>number</code> | <code>0</code> |
| [repeat] | <code>number</code> | <code>0</code> |
| [dispose] | <code>number</code> | <code>-1</code> |
<a name="H264MP4EncoderOptions"></a>
## H264MP4EncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ---------------- | -------------------------------------------------------------------------- | --------------- |
| [debug] | <code>boolean</code> | |
| [encoderOptions] | [<code>H264MP4EncoderEncoderOptions</code>](#H264MP4EncoderEncoderOptions) | <code>{}</code> |
<a name="H264MP4EncoderEncoderOptions"></a>
## H264MP4EncoderEncoderOptions : <code>module:h264-mp4-encoder~H264MP4Encoder</code>
**Kind**: global typedef
**See**: [h264-mp4-encoder#api](https://github.com/TrevorSundberg/h264-mp4-encoder#api)
<a name="MP4WasmEncoderOptions"></a>
## MP4WasmEncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ----------------- | -------------------------------------------------------------------------- | --------------- |
| [groupOfPictures] | <code>number</code> | <code>20</code> |
| [flushFrequency] | <code>number</code> | <code>10</code> |
| [encoderOptions] | [<code>MP4WasmEncoderEncoderOptions</code>](#MP4WasmEncoderEncoderOptions) | <code>{}</code> |
<a name="MP4WasmEncoderEncoderOptions"></a>
## MP4WasmEncoderEncoderOptions : <code>VideoEncoderConfig</code>
**Kind**: global typedef
**See**: [VideoEncoder.configure](https://developer.mozilla.org/en-US/docs/Web/API/VideoEncoder/configure#config)
<a name="MediaCaptureEncoderOptions"></a>
## MediaCaptureEncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ---------------- | ------------------------------------------------------------------------------------ | --------------- |
| [flushFrequency] | <code>number</code> | <code>10</code> |
| [encoderOptions] | [<code>MediaCaptureEncoderEncoderOptions</code>](#MediaCaptureEncoderEncoderOptions) | <code>{}</code> |
<a name="MediaCaptureEncoderEncoderOptions"></a>
## MediaCaptureEncoderEncoderOptions : <code>MediaRecorderOptions</code>
**Kind**: global typedef
**See**: [MediaRecorder#options](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder#options)
<a name="WebCodecsEncoderOptions"></a>
## WebCodecsEncoderOptions : <code>object</code>
**Kind**: global typedef
**Properties**
| Name | Type | Default |
| ----------------- | ------------------------------------------------------------------------------ | --------------- |
| [groupOfPictures] | <code>number</code> | <code>20</code> |
| [flushFrequency] | <code>number</code> | <code>10</code> |
| [encoderOptions] | [<code>WebCodecsEncoderEncoderOptions</code>](#WebCodecsEncoderEncoderOptions) | <code>{}</code> |
<a name="WebCodecsEncoderEncoderOptions"></a>
## WebCodecsEncoderEncoderOptions : <code>VideoEncoderConfig</code>
**Kind**: global typedef
**See**: [VideoEncoder.configure](https://developer.mozilla.org/en-US/docs/Web/API/VideoEncoder/configure#config)
<a name="WebCodecsMuxerOptions"></a>
## WebCodecsMuxerOptions : <code>MuxerOptions</code>
**Kind**: global typedef
**See**
- [Mp4.MuxerOptions](https://github.com/Vanilagy/mp4-muxer/#usage)
- [WebM.MuxerOptions](https://github.com/Vanilagy/webm-muxer/#usage)
<!-- api-end -->

@@ -300,0 +730,0 @@

@@ -0,4 +1,20 @@

/**
* @typedef {"mp4" | "webm" | "png" | "jpg" | "gif" | "mkv"} EncoderExtensions
*/
/**
* @typedef {"in-browser" | "file-system"} EncoderTarget
*/
class Encoder {
/**
* The extension the encoder supports
* @type {Extensions[]}
*/
static supportedExtensions = ["mp4", "webm"];
static supportedTargets = ["in-browser"]; // or "file-system"
/**
* The target to download the file to.
* @type {EncoderTarget[]}
*/
static supportedTargets = ["in-browser"];

@@ -11,2 +27,12 @@ static defaultOptions = {

/**
* Base Encoder class. All Encoders extend it and its method are called by the Recorder.
* @class Encoder
* @param {object} options
*
* @property {EncoderTarget} target
* @property {EncoderExtensions} extension
* @property {object} [encoderOptions]
* @property {object} [muxerOptions]
*/
constructor(options) {

@@ -16,2 +42,6 @@ Object.assign(this, options);

/**
* Setup the encoder: load binary, instantiate muxers, setup file system target...
* @param {object} options
*/
async init(options) {

@@ -54,7 +84,17 @@ Object.assign(this, options);

/**
* Encode a single frame. The frameNumber is usually used for GOP (Group Of Pictures).
* @param {number} frame
* @param {number} frameNumber
* @param {number} [frameNumber]
*/
async encode() {}
/**
* Stop the encoding process and cleanup the temporary data.
* @returns {(ArrayBuffer|Uint8Array|Blob[]|undefined)}
*/
async stop() {}
/**
* Clean up the encoder
*/
dispose() {}

@@ -61,0 +101,0 @@ }

@@ -1,2 +0,3 @@

import FFmpeg from "@ffmpeg/ffmpeg";
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { fetchFile } from "@ffmpeg/util";

@@ -7,15 +8,31 @@ import Encoder from "./Encoder.js";

/**
* @typedef {object} FFmpegEncoderOptions
* @property {FFmpegEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {import("@ffmpeg/ffmpeg/dist/esm/types.js").FFMessageLoadConfig} FFmpegEncoderEncoderOptions
* @see [FFmpeg#load]{@link https://ffmpegwasm.netlify.app/docs/api/ffmpeg/classes/FFmpeg#load}
*/
class FFmpegEncoder extends Encoder {
static supportedExtensions = ["mp4", "webm"];
/**
* @param {FFmpegEncoderOptions} [options]
*/
constructor(options) {
super(options);
}
async init(options) {
super.init(options);
this.encoder = FFmpeg.createFFmpeg({
corePath: "https://unpkg.com/@ffmpeg/core@0.11.0/dist/ffmpeg-core.js",
log: this.debug,
...this.encoderOptions,
this.encoder = new FFmpeg();
this.encoder.on("log", ({ message }) => {
console.log(message);
});
await this.encoder.load();
await this.encoder.load({ ...this.encoderOptions });
this.frameCount = 0;

@@ -25,6 +42,5 @@ }

async encode(frame, frameNumber) {
this.encoder.FS(
"writeFile",
await this.encoder.writeFile(
getFrameName(frameNumber),
await FFmpeg.fetchFile(frame)
await fetchFile(frame),
);

@@ -37,13 +53,14 @@ this.frameCount++;

const codec = this.extension === "mp4" ? "libx264" : "libvpx";
await this.encoder.run(
...`-framerate ${this.frameRate} -pattern_type glob -i *.png -s ${this.width}x${this.height} -pix_fmt yuv420p -c:v ${codec} ${outputFilename}`.split(
" "
)
await this.encoder.exec(
`-framerate ${this.frameRate} -pattern_type glob -i *.png -s ${this.width}x${this.height} -pix_fmt yuv420p -c:v ${codec} ${outputFilename}`.split(
" ",
),
);
const data = await this.encoder.FS("readFile", outputFilename);
const data = await this.encoder.readFile(outputFilename);
for (let i = 0; i < this.frameCount; i++) {
try {
this.encoder.FS("unlink", getFrameName(i));
this.encoder.deleteFile(getFrameName(i));
} catch (error) {

@@ -55,3 +72,3 @@ console.error(error);

try {
this.encoder.FS("unlink", outputFilename);
this.encoder.deleteFile(outputFilename);
} catch (error) {

@@ -64,4 +81,4 @@ console.error(error);

dispose() {
this.encoder.exit();
async dispose() {
await this.encoder.terminate();
this.encoder = null;

@@ -68,0 +85,0 @@ }

@@ -5,2 +5,3 @@ import Encoder from "./Encoder.js";

/** @class */
class FrameEncoder extends Encoder {

@@ -11,4 +12,4 @@ static supportedExtensions = ["png", "jpg"];

static defaultOptions = {
extension: FrameEncoder.supportedExtensions[0],
frameMethod: "blob",
extension: FrameEncoder.supportedExtensions[0],
};

@@ -27,3 +28,3 @@

this.directory,
this.filename
this.filename,
);

@@ -53,3 +54,3 @@ }

`${`${frameNumber}`.padStart(5, "0")}.${this.extension}`,
frame
frame,
);

@@ -56,0 +57,0 @@ }

import { GIFEncoder as GIFEnc, quantize, applyPalette } from "gifenc";
import Encoder from "./Encoder.js";
/**
* @typedef {object} GIFEncoderOptions
* @property {number} [maxColors=256]
* @property {GIFEncoderQuantizeOptions} [quantizeOptions]
* @property {GIFEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {object} GIFEncoderQuantizeOptions
* @property {"rgb565" | "rgb444" | "rgba4444"} [format="rgb565"]
* @property {boolean | number} [oneBitAlpha=false]
* @property {boolean} [clearAlpha=true]
* @property {number} [clearAlphaThreshold=0]
* @property {number} [clearAlphaColor=0x00]
* @see [QuantizeOptions]{@link https://github.com/mattdesl/gifenc#palette--quantizergba-maxcolors-options--}
*/
/**
* @typedef {object} GIFEncoderEncoderOptions
* @property {number[][]} [palette]
* @property {boolean} [first=false]
* @property {boolean} [transparent=0]
* @property {number} [transparentIndex=0]
* @property {number} [delay=0]
* @property {number} [repeat=0]
* @property {number} [dispose=-1]
* @see [WriteFrameOpts]{@link https://github.com/mattdesl/gifenc#gifwriteframeindex-width-height-opts--}
*/
class GIFEncoder extends Encoder {

@@ -20,2 +48,5 @@ static supportedExtensions = ["gif"];

/**
* @param {GIFEncoderOptions} [options]
*/
constructor(options) {

@@ -22,0 +53,0 @@ super({ ...GIFEncoder.defaultOptions, ...options });

@@ -1,7 +0,16 @@

import { createH264MP4Encoder } from "h264-mp4-encoder";
import HME from "h264-mp4-encoder";
import Encoder from "./Encoder.js";
import { nextMultiple } from "../utils.js";
import { estimateBitRate, nextMultiple } from "../utils.js";
/**
* @typedef {object} H264MP4EncoderOptions
* @property {boolean} [debug]
* @property {H264MP4EncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {import("h264-mp4-encoder").H264MP4Encoder} H264MP4EncoderEncoderOptions
* @see [h264-mp4-encoder#api]{@link https://github.com/TrevorSundberg/h264-mp4-encoder#api}
*/
class H264MP4Encoder extends Encoder {

@@ -15,2 +24,5 @@ static supportedExtensions = ["mp4"];

/**
* @param {H264MP4EncoderOptions} [options]
*/
constructor(options) {

@@ -23,3 +35,3 @@ super({ ...H264MP4Encoder.defaultOptions, ...options });

this.encoder = await createH264MP4Encoder();
this.encoder = await HME.createH264MP4Encoder();

@@ -31,3 +43,3 @@ Object.assign(this.encoder, {

frameRate: this.frameRate, // 30
// kbps: 0, // The bitrate in kbps relative to the frame_rate. Overwrites quantization_parameter if not 0.
kbps: estimateBitRate(this.width, this.height, this.frameRate) / 1000, // The bitrate in kbps relative to the frame_rate. Overwrites quantization_parameter if not 0.
// speed: 0, // Speed where 0 means best quality and 10 means fastest speed [0..10].

@@ -34,0 +46,0 @@ // quantizationParameter: 33, // Higher means better compression, and lower means better quality [10..51].

@@ -5,2 +5,13 @@ import Encoder from "./Encoder.js";

/**
* @typedef {object} MediaCaptureEncoderOptions
* @property {number} [flushFrequency=10]
* @property {MediaCaptureEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {MediaRecorderOptions} MediaCaptureEncoderEncoderOptions
* @see [MediaRecorder#options]{@link https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder#options}
*/
class MediaCaptureEncoder extends Encoder {

@@ -11,6 +22,9 @@ static supportedExtensions = ["mkv", "webm"];

extension: MediaCaptureEncoder.supportedExtensions[0],
frameMethod: "requestFrame",
flushFrequency: 10,
frameMethod: "requestFrame",
};
/**
* @param {MediaCaptureEncoderOptions} [options]
*/
constructor(options) {

@@ -17,0 +31,0 @@ super({ ...MediaCaptureEncoder.defaultOptions, ...options });

import MP4Wasm from "./mp4.embed.js"; // mp4-wasm
import Encoder from "./Encoder.js";
import { estimateBitRate } from "../utils.js";
/**
* @typedef {object} MP4WasmEncoderOptions
* @property {number} [groupOfPictures=20]
* @property {number} [flushFrequency=10]
* @property {MP4WasmEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {VideoEncoderConfig} MP4WasmEncoderEncoderOptions
* @see [VideoEncoder.configure]{@link https://developer.mozilla.org/en-US/docs/Web/API/VideoEncoder/configure#config}
*/
let mp4wasm;

@@ -21,2 +33,5 @@

/**
* @param {MP4WasmEncoderOptions} [options]
*/
constructor(options) {

@@ -39,2 +54,8 @@ super({ ...MP4WasmEncoder.defaultOptions, ...options });

framerate: this.frameRate,
bitrate: estimateBitRate(
this.width,
this.height,
this.frameRate,
this.encoderOptions.bitrateMode,
),
...this.encoderOptions,

@@ -41,0 +62,0 @@ },

@@ -6,3 +6,20 @@ import * as MP4Muxer from "mp4-muxer";

import Encoder from "./Encoder.js";
import { estimateBitRate } from "../utils.js";
/**
* @typedef {object} WebCodecsEncoderOptions
* @property {number} [groupOfPictures=20]
* @property {number} [flushFrequency=10]
* @property {WebCodecsEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {VideoEncoderConfig} WebCodecsEncoderEncoderOptions
* @see [VideoEncoder.configure]{@link https://developer.mozilla.org/en-US/docs/Web/API/VideoEncoder/configure#config}
*/
/**
* @typedef {MuxerOptions} WebCodecsMuxerOptions
* @see [Mp4.MuxerOptions]{@link https://github.com/Vanilagy/mp4-muxer/#usage}
* @see [WebM.MuxerOptions]{@link https://github.com/Vanilagy/webm-muxer/#usage}
*/
class WebCodecsEncoder extends Encoder {

@@ -22,2 +39,5 @@ static supportedExtensions = ["mp4", "webm", "mkv"];

/**
* @param {WebCodecsEncoderOptions} [options]
*/
constructor(options) {

@@ -74,2 +94,3 @@ super({ ...WebCodecsEncoder.defaultOptions, ...options });

firstTimestampBehavior: "offset", // "strict" | "offset" | "permissive"
fastStart: this.writableFileStream ? false : "in-memory",
...this.muxerOptions,

@@ -86,4 +107,10 @@ });

height: this.height,
frameRate: this.frameRate,
bitrate: 1e6,
framerate: this.frameRate,
bitrate: estimateBitRate(
this.width,
this.height,
this.frameRate,
this.encoderOptions.bitrateMode,
),
// bitrate: 1e6,
// alpha: "discard", // "keep"

@@ -101,4 +128,4 @@ // bitrateMode: "variable", // "constant"

`canvas-record: Unsupported VideoEncoder config\n ${JSON.stringify(
config
)}`
config,
)}`,
);

@@ -105,0 +132,0 @@ }

@@ -39,4 +39,3 @@ import canvasScreenshot from "canvas-screenshot";

* A callback to notify on the status change. To compare with RecorderStatus enum values.
* @name onStatusChangeCb
* @function
* @callback onStatusChangeCb
* @param {number} RecorderStatus the status

@@ -51,3 +50,3 @@ */

* @property {boolean} [download=true] Automatically download the recording when duration is reached or when `await canvasRecorder.stop()` is manually called.
* @property {boolean} [extension="mp4"] Default file extension: infers which Encoder is selected.
* @property {string} [extension="mp4"] Default file extension: infers which Encoder is selected.
* @property {string} [target="in-browser"] Default writing target: in-browser or file-system when available.

@@ -61,3 +60,3 @@ * @property {object} [encoder] A specific encoder. Default encoder based on options.extension: GIF > WebCodecs > H264MP4.

/**
* @typedef {object} RecorderStartOptions Options for recording. All optional.
* @typedef {object} RecorderStartOptions Options for recording initialisation. All optional.
* @property {string} [filename] Overwrite the file name completely.

@@ -67,7 +66,7 @@ * @property {boolean} [initOnly] Only initialised the recorder and don't call the first await recorder.step().

/**
* Base Recorder class.
* @property {boolean} [enabled=true] Enable/disable pointer interaction and drawing.
*/
class Recorder {
/**
* Sensible defaults for recording so that the recorder "just works".
* @type {RecorderOptions}
*/
static defaultOptions = {

@@ -83,2 +82,6 @@ name: "",

/**
* A mapping of extension to their mime types
* @type {object}
*/
static mimeTypes = {

@@ -141,3 +144,3 @@ mkv: "video/x-matroska;codecs=avc1",

const isExtensionSupported = CurrentEncoder.supportedExtensions.includes(
this.extension
this.extension,
);

@@ -150,3 +153,3 @@ const extension = isExtensionSupported

console.warn(
`canvas-record: unsupported extension for encoder "${CurrentEncoder.name}". Defaulting to "${extension}".`
`canvas-record: unsupported extension for encoder "${CurrentEncoder.name}". Defaulting to "${extension}".`,
);

@@ -160,3 +163,3 @@ }

let isTargetSupported = CurrentEncoder.supportedTargets.includes(
this.target
this.target,
);

@@ -174,3 +177,3 @@

console.warn(
`canvas-record: unsupported target for encoder "${CurrentEncoder.name}". Defaulting to "${target}".`
`canvas-record: unsupported target for encoder "${CurrentEncoder.name}". Defaulting to "${target}".`,
);

@@ -182,4 +185,6 @@ }

/**
* Create a Recorder instance
* @class Recorder
* @param {RenderingContext} context
* @param {RecorderOptions} options
* @param {RecorderOptions} [options={}]
*/

@@ -244,3 +249,3 @@ constructor(context, options = {}) {

* Start the recording by initializing and optionally calling the initial step.
* @param {RecorderStartOptions} startOptions
* @param {RecorderStartOptions} [startOptions={}]
*/

@@ -293,3 +298,3 @@ async start(startOptions = {}) {

this.context.UNSIGNED_BYTE,
pixels
pixels,
);

@@ -311,3 +316,3 @@

nextMultiple(this.width, 2),
nextMultiple(this.height, 2)
nextMultiple(this.height, 2),
).data;

@@ -336,3 +341,3 @@ }

await this.getFrame(this.encoder.frameMethod),
this.frame
this.frame,
);

@@ -363,3 +368,3 @@ this.time += this.deltaTime;

Array.isArray(buffer) ? buffer : [buffer],
this.encoder.mimeType
this.encoder.mimeType,
);

@@ -373,3 +378,3 @@ }

/**
* Clean up
* Clean up the recorder and encoder
*/

@@ -376,0 +381,0 @@ async dispose() {

@@ -0,1 +1,5 @@

/**
* Check for WebCodecs support on the current platform.
* @type {boolean}
*/
const isWebCodecsSupported =

@@ -29,3 +33,3 @@ typeof window !== "undefined" && typeof window.VideoEncoder === "function";

return `${String(minutes).padStart(2, "0")}:${String(
remainingSeconds
remainingSeconds,
).padStart(2, "0")}`;

@@ -48,2 +52,37 @@ };

/**
* Estimate the bit rate of a video rounded to nearest megabit.
* Based on "H.264 for the rest of us" by Kush Amerasinghe.
*
* @example
* ```js
* // Full HD (1080p)
* const bitRate = estimateBitRate(1920, 1080, 30, "variable");
* const bitRateMbps = bitRate * 1_000_000; // => 13 Mbps
* ```
*
* @param {number} width
* @param {number} height
* @param {number} frameRate
* @param {number} motionRank A factor of 1, 2 or 4
* @param {"variable" | "constant"} bitrateMode
* @returns {number} A bitrate value in bits per second
*/
const estimateBitRate = (
width,
height,
frameRate = 30,
motionRank = 4,
bitrateMode = "variable",
) =>
Math.round(
(width *
height *
frameRate *
motionRank *
0.07 *
(bitrateMode === "variable" ? 0.75 : 1)) /
1_000_000,
) * 1_000_000;
export {

@@ -56,2 +95,3 @@ isWebCodecsSupported,

Deferred,
estimateBitRate,
};
export default Encoder;
export type EncoderExtensions = "mp4" | "webm" | "png" | "jpg" | "gif" | "mkv";
export type EncoderTarget = "in-browser" | "file-system";
/**
* @typedef {"mp4" | "webm" | "png" | "jpg" | "gif" | "mkv"} EncoderExtensions
*/
/**
* @typedef {"in-browser" | "file-system"} EncoderTarget
*/
declare class Encoder {
static supportedExtensions: string[];
static supportedTargets: string[];
/**
* The extension the encoder supports
* @type {Extensions[]}
*/
static supportedExtensions: Extensions[];
/**
* The target to download the file to.
* @type {EncoderTarget[]}
*/
static supportedTargets: EncoderTarget[];
static defaultOptions: {
frameMethod: string;
extension: string;
target: string;
extension: Extensions;
target: EncoderTarget;
};
constructor(options: any);
init(options: any): Promise<void>;
/**
* Base Encoder class. All Encoders extend it and its method are called by the Recorder.
* @class Encoder
* @param {object} options
*
* @property {EncoderTarget} target
* @property {EncoderExtensions} extension
* @property {object} [encoderOptions]
* @property {object} [muxerOptions]
*/
constructor(options: object);
/**
* Setup the encoder: load binary, instantiate muxers, setup file system target...
* @param {object} options
*/
init(options: object): Promise<void>;
getDirectory(): Promise<FileSystemDirectoryHandle>;

@@ -17,8 +47,16 @@ getDirectoryHandle(directory: any, name: any): Promise<any>;

/**
* Encode a single frame. The frameNumber is usually used for GOP (Group Of Pictures).
* @param {number} frame
* @param {number} frameNumber
* @param {number} [frameNumber]
*/
encode(): Promise<void>;
stop(): Promise<void>;
/**
* Stop the encoding process and cleanup the temporary data.
* @returns {(ArrayBuffer|Uint8Array|Blob[]|undefined)}
*/
stop(): (ArrayBuffer | Uint8Array | Blob[] | undefined);
/**
* Clean up the encoder
*/
dispose(): void;
}
export default FFmpegEncoder;
export type FFmpegEncoderOptions = {
encoderOptions?: any;
};
export type FFmpegEncoderEncoderOptions = any;
/**
* @typedef {object} FFmpegEncoderOptions
* @property {FFmpegEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {import("@ffmpeg/ffmpeg/dist/esm/types.js").FFMessageLoadConfig} FFmpegEncoderEncoderOptions
* @see [FFmpeg#load]{@link https://ffmpegwasm.netlify.app/docs/api/ffmpeg/classes/FFmpeg#load}
*/
declare class FFmpegEncoder extends Encoder {
static supportedExtensions: string[];
/**
* @param {FFmpegEncoderOptions} [options]
*/
constructor(options?: FFmpegEncoderOptions);
init(options: any): Promise<void>;
encoder: any;

@@ -7,3 +25,4 @@ frameCount: number;

stop(): Promise<any>;
dispose(): Promise<void>;
}
import Encoder from "./Encoder.js";
export default FrameEncoder;
/** @class */
declare class FrameEncoder extends Encoder {
static supportedExtensions: string[];
static supportedTargets: string[];
static defaultOptions: {
extension: string;
frameMethod: string;
extension: string;
};
constructor(options: any);
init(options: any): Promise<void>;
directoryHandle: any;

@@ -8,0 +13,0 @@ writeFile(frameFileName: any, blob: any): Promise<void>;

export default GIFEncoder;
export type GIFEncoderOptions = {
maxColors?: number;
quantizeOptions?: GIFEncoderQuantizeOptions;
encoderOptions?: GIFEncoderEncoderOptions;
};
export type GIFEncoderQuantizeOptions = {
format?: "rgb565" | "rgb444" | "rgba4444";
oneBitAlpha?: boolean | number;
clearAlpha?: boolean;
clearAlphaThreshold?: number;
clearAlphaColor?: number;
};
export type GIFEncoderEncoderOptions = {
palette?: number[][];
first?: boolean;
transparent?: boolean;
transparentIndex?: number;
delay?: number;
repeat?: number;
dispose?: number;
};
/**
* @typedef {object} GIFEncoderOptions
* @property {number} [maxColors=256]
* @property {GIFEncoderQuantizeOptions} [quantizeOptions]
* @property {GIFEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {object} GIFEncoderQuantizeOptions
* @property {"rgb565" | "rgb444" | "rgba4444"} [format="rgb565"]
* @property {boolean | number} [oneBitAlpha=false]
* @property {boolean} [clearAlpha=true]
* @property {number} [clearAlphaThreshold=0]
* @property {number} [clearAlphaColor=0x00]
* @see [QuantizeOptions]{@link https://github.com/mattdesl/gifenc#palette--quantizergba-maxcolors-options--}
*/
/**
* @typedef {object} GIFEncoderEncoderOptions
* @property {number[][]} [palette]
* @property {boolean} [first=false]
* @property {boolean} [transparent=0]
* @property {number} [transparentIndex=0]
* @property {number} [delay=0]
* @property {number} [repeat=0]
* @property {number} [dispose=-1]
* @see [WriteFrameOpts]{@link https://github.com/mattdesl/gifenc#gifwriteframeindex-width-height-opts--}
*/
declare class GIFEncoder extends Encoder {
static supportedExtensions: string[];
static defaultOptions: {

@@ -15,2 +63,7 @@ extension: string;

};
/**
* @param {GIFEncoderOptions} [options]
*/
constructor(options?: GIFEncoderOptions);
init(options: any): Promise<void>;
encoder: any;

@@ -17,0 +70,0 @@ start(): Promise<void>;

export default H264MP4Encoder;
export type H264MP4EncoderOptions = {
debug?: boolean;
encoderOptions?: any;
};
export type H264MP4EncoderEncoderOptions = any;
/**
* @typedef {object} H264MP4EncoderOptions
* @property {boolean} [debug]
* @property {H264MP4EncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {import("h264-mp4-encoder").H264MP4Encoder} H264MP4EncoderEncoderOptions
* @see [h264-mp4-encoder#api]{@link https://github.com/TrevorSundberg/h264-mp4-encoder#api}
*/
declare class H264MP4Encoder extends Encoder {
static supportedExtensions: string[];
static defaultOptions: {

@@ -7,7 +22,12 @@ extension: string;

};
encoder: import("h264-mp4-encoder").H264MP4Encoder;
/**
* @param {H264MP4EncoderOptions} [options]
*/
constructor(options?: H264MP4EncoderOptions);
init(options: any): Promise<void>;
encoder: any;
start(): Promise<void>;
encode(frame: any): void;
stop(): Uint8Array;
stop(): any;
}
import Encoder from "./Encoder.js";
export default MediaCaptureEncoder;
export type MediaCaptureEncoderOptions = {
flushFrequency?: number;
encoderOptions?: MediaCaptureEncoderEncoderOptions;
};
export type MediaCaptureEncoderEncoderOptions = MediaRecorderOptions;
/**
* @typedef {object} MediaCaptureEncoderOptions
* @property {number} [flushFrequency=10]
* @property {MediaCaptureEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {MediaRecorderOptions} MediaCaptureEncoderEncoderOptions
* @see [MediaRecorder#options]{@link https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder#options}
*/
declare class MediaCaptureEncoder extends Encoder {
static supportedExtensions: string[];
static defaultOptions: {
extension: string;
frameMethod: string;
flushFrequency: number;
frameMethod: string;
};
/**
* @param {MediaCaptureEncoderOptions} [options]
*/
constructor(options?: MediaCaptureEncoderOptions);
init(options: any): Promise<void>;
chunks: any[];

@@ -9,0 +29,0 @@ stream: any;

export default MP4WasmEncoder;
export type MP4WasmEncoderOptions = {
groupOfPictures?: number;
flushFrequency?: number;
encoderOptions?: MP4WasmEncoderEncoderOptions;
};
export type MP4WasmEncoderEncoderOptions = VideoEncoderConfig;
declare class MP4WasmEncoder extends Encoder {
static supportedExtensions: string[];
static supportedTargets: string[];
static defaultOptions: {

@@ -8,3 +16,8 @@ extension: string;

};
/**
* @param {MP4WasmEncoderOptions} [options]
*/
constructor(options?: MP4WasmEncoderOptions);
get frameMethod(): string;
init(options: any): Promise<void>;
encoder: any;

@@ -11,0 +24,0 @@ encode(frame: any): Promise<void>;

export default WebCodecsEncoder;
export type WebCodecsEncoderOptions = {
groupOfPictures?: number;
flushFrequency?: number;
encoderOptions?: WebCodecsEncoderEncoderOptions;
};
export type WebCodecsEncoderEncoderOptions = VideoEncoderConfig;
export type WebCodecsMuxerOptions = MuxerOptions;
/**
* @typedef {object} WebCodecsEncoderOptions
* @property {number} [groupOfPictures=20]
* @property {number} [flushFrequency=10]
* @property {WebCodecsEncoderEncoderOptions} [encoderOptions={}]
*/
/**
* @typedef {VideoEncoderConfig} WebCodecsEncoderEncoderOptions
* @see [VideoEncoder.configure]{@link https://developer.mozilla.org/en-US/docs/Web/API/VideoEncoder/configure#config}
*/
/**
* @typedef {MuxerOptions} WebCodecsMuxerOptions
* @see [Mp4.MuxerOptions]{@link https://github.com/Vanilagy/mp4-muxer/#usage}
* @see [WebM.MuxerOptions]{@link https://github.com/Vanilagy/webm-muxer/#usage}
*/
declare class WebCodecsEncoder extends Encoder {
static supportedExtensions: string[];
static supportedTargets: string[];
static defaultOptions: {

@@ -8,5 +32,10 @@ extension: string;

};
/**
* @param {WebCodecsEncoderOptions} [options]
*/
constructor(options?: WebCodecsEncoderOptions);
get frameMethod(): string;
init(options: any): Promise<void>;
writableFileStream: any;
muxer: MP4Muxer.Muxer<MP4Muxer.ArrayBufferTarget | MP4Muxer.StreamTarget | MP4Muxer.FileSystemWritableFileStreamTarget> | WebMMuxer.Muxer<MP4Muxer.ArrayBufferTarget | MP4Muxer.StreamTarget | MP4Muxer.FileSystemWritableFileStreamTarget>;
muxer: any;
encoder: VideoEncoder;

@@ -18,3 +47,1 @@ encode(frame: any, number: any): Promise<void>;

import Encoder from "./Encoder.js";
import * as MP4Muxer from "mp4-muxer";
import * as WebMMuxer from "webm-muxer";
/**
* A callback to notify on the status change. To compare with RecorderStatus enum values.
*/
export type onStatusChangeCb = (RecorderStatus: number) => any;
/**
* Options for recording. All optional.

@@ -24,3 +28,3 @@ */

*/
extension?: boolean;
extension?: string;
/**

@@ -45,3 +49,3 @@ * Default writing target: in-browser or file-system when available.

/**
* Options for recording. All optional.
* Options for recording initialisation. All optional.
*/

@@ -60,4 +64,3 @@ export type RecorderStartOptions = {

* A callback to notify on the status change. To compare with RecorderStatus enum values.
* @name onStatusChangeCb
* @function
* @callback onStatusChangeCb
* @param {number} RecorderStatus the status

@@ -71,3 +74,3 @@ */

* @property {boolean} [download=true] Automatically download the recording when duration is reached or when `await canvasRecorder.stop()` is manually called.
* @property {boolean} [extension="mp4"] Default file extension: infers which Encoder is selected.
* @property {string} [extension="mp4"] Default file extension: infers which Encoder is selected.
* @property {string} [target="in-browser"] Default writing target: in-browser or file-system when available.

@@ -80,29 +83,22 @@ * @property {object} [encoder] A specific encoder. Default encoder based on options.extension: GIF > WebCodecs > H264MP4.

/**
* @typedef {object} RecorderStartOptions Options for recording. All optional.
* @typedef {object} RecorderStartOptions Options for recording initialisation. All optional.
* @property {string} [filename] Overwrite the file name completely.
* @property {boolean} [initOnly] Only initialised the recorder and don't call the first await recorder.step().
*/
/**
* Base Recorder class.
* @property {boolean} [enabled=true] Enable/disable pointer interaction and drawing.
*/
export class Recorder {
static defaultOptions: {
name: string;
duration: number;
frameRate: number;
download: boolean;
extension: string;
target: string;
onStatusChange: () => void;
};
static mimeTypes: {
mkv: string;
webm: string;
mp4: string;
gif: string;
};
/**
* Sensible defaults for recording so that the recorder "just works".
* @type {RecorderOptions}
*/
static defaultOptions: RecorderOptions;
/**
* A mapping of extension to their mime types
* @type {object}
*/
static mimeTypes: object;
/**
* Create a Recorder instance
* @class Recorder
* @param {RenderingContext} context
* @param {RecorderOptions} options
* @param {RecorderOptions} [options={}]
*/

@@ -139,3 +135,3 @@ constructor(context: RenderingContext, options?: RecorderOptions);

* Start the recording by initializing and optionally calling the initial step.
* @param {RecorderStartOptions} startOptions
* @param {RecorderStartOptions} [startOptions={}]
*/

@@ -161,3 +157,3 @@ start(startOptions?: RecorderStartOptions): Promise<void>;

/**
* Clean up
* Clean up the recorder and encoder
*/

@@ -164,0 +160,0 @@ dispose(): Promise<void>;

@@ -0,1 +1,5 @@

/**
* Check for WebCodecs support on the current platform.
* @type {boolean}
*/
export const isWebCodecsSupported: boolean;

@@ -11,1 +15,20 @@ export function downloadBlob(filename: any, blobPart: any, mimeType: any): void;

}
/**
* Estimate the bit rate of a video rounded to nearest megabit.
* Based on "H.264 for the rest of us" by Kush Amerasinghe.
*
* @example
* ```js
* // Full HD (1080p)
* const bitRate = estimateBitRate(1920, 1080, 30, "variable");
* const bitRateMbps = bitRate * 1_000_000; // => 13 Mbps
* ```
*
* @param {number} width
* @param {number} height
* @param {number} frameRate
* @param {number} motionRank A factor of 1, 2 or 4
* @param {"variable" | "constant"} bitrateMode
* @returns {number} A bitrate value in bits per second
*/
export function estimateBitRate(width: number, height: number, frameRate?: number, motionRank?: number, bitrateMode?: "variable" | "constant"): number;

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc