Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffmpeg.wasm plugin #522

Merged
merged 28 commits into from
Jan 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
65dd670
add ffmpeg.wasm example
thijstriemstra Nov 14, 2020
413489c
add @ffmpeg libs
thijstriemstra Nov 14, 2020
3cd5064
add SharedArrayBuffer headers for Firefox
thijstriemstra Nov 14, 2020
7b47069
fix typo
thijstriemstra Nov 14, 2020
38901e3
add ffmpeg.wasm plugin
thijstriemstra Nov 14, 2020
d7df8df
fix lint issue
thijstriemstra Nov 14, 2020
65e153a
try latest
thijstriemstra Nov 18, 2020
4f1ad58
Merge branch 'master' into ffmpeg-wasm
thijstriemstra Dec 9, 2020
e8a8888
Merge branch 'master' into ffmpeg-wasm
thijstriemstra Jan 5, 2021
e58159e
Merge branch 'master' into ffmpeg-wasm
thijstriemstra Jan 24, 2021
bc209a4
merge forward
thijstriemstra Jan 30, 2021
a0d109d
bump required version for videojs-wavesurfer
thijstriemstra Jan 30, 2021
8d183c1
add missing import
thijstriemstra Jan 30, 2021
2aa3f1c
add changelog entry
thijstriemstra Jan 30, 2021
f9fa047
fix lint error
thijstriemstra Jan 30, 2021
16f37e2
ci: lint on ga
thijstriemstra Jan 30, 2021
b7bb0ee
add @ffmpeg
thijstriemstra Jan 30, 2021
e561be4
add test
thijstriemstra Jan 30, 2021
10dd4e7
doc update
thijstriemstra Jan 31, 2021
ee2b206
fix implementation
thijstriemstra Jan 31, 2021
52c902f
doc update
thijstriemstra Jan 31, 2021
b435bc1
fix test
thijstriemstra Jan 31, 2021
7ec4d1a
fix typo
thijstriemstra Jan 31, 2021
1ec57e0
mark as deprecated
thijstriemstra Jan 31, 2021
6dafb89
disable test
thijstriemstra Jan 31, 2021
d21f543
add demo
thijstriemstra Jan 31, 2021
b030a61
use unpkg
thijstriemstra Jan 31, 2021
df4e3ab
doc update
thijstriemstra Jan 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jobs:
${{ runner.OS }}-
- name: Install Node.js modules
run: npm ci
- name: Lint
run: npm run lint
- name: Build
run: npm run build
- name: Test
Expand Down
8 changes: 6 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

## 4.2.0 - unreleased

- New opus-media-recorder plugin: provides cross-browser Opus codec support with
various audio formats such as Ogg and WebM (#355)
- New ffmpeg.wasm converter plugin: convert recorded data into other
audio/video/image file formats (#522)
- New opus-media-recorder plugin: provides cross-browser Opus codec
support for various audio formats such as Ogg and WebM (#355)
- ffmpeg.js plugin is deprecated; use new ffmpeg.wasm plugin instead
- Bump required version for videojs-wavesurfer (3.4.0 or newer)


## 4.1.1 - 2020/11/01
Expand Down
10 changes: 10 additions & 0 deletions build-config/fragments/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ module.exports = {
console.log(colors.green(' [examples] wasm mime-type handler ready'));
console.log('');

// ========================================================
// use proper headers for SharedArrayBuffer on Firefox
// see https://github.com/ffmpegwasm/ffmpeg.wasm/issues/102
// ========================================================
app.use((req, res, next) => {
res.header('Cross-Origin-Opener-Policy', 'same-origin');
res.header('Cross-Origin-Embedder-Policy', 'require-corp');
next();
});

// =============================================
// file upload handler for simple upload example
// =============================================
Expand Down
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [UmiJS](frameworks/umijs.md)

- Plugins
- [ffmpeg.wasm](plugins/ffmpeg.wasm.md)
- [ffmpeg.js](plugins/ffmpeg.js.md)
- [ts-ebml](plugins/ts-ebml.md)
- [webm-wasm](plugins/webm-wasm.md)
Expand Down
99 changes: 99 additions & 0 deletions docs/demo/video-only-ffmpegwasm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>ffmpeg.wasm video-only example - Record Plugin for Video.js</title>

<link href="//vjs.zencdn.net/7.10.2/video-js.min.css" rel="stylesheet">
<link href="//unpkg.com/videojs-record/dist/css/videojs.record.min.css" rel="stylesheet">
<link href="assets/examples.css" rel="stylesheet">

<script src="//vjs.zencdn.net/7.10.2/video.min.js"></script>
<script src="//unpkg.com/recordrtc/RecordRTC.js"></script>
<script src="//unpkg.com/webrtc-adapter/out/adapter.js"></script>
<script src="//unpkg.com/@ffmpeg/ffmpeg/dist/ffmpeg.min.js"></script>

<script src="//unpkg.com/videojs-record/dist/videojs.record.min.js"></script>
<script src="//unpkg.com/videojs-record/dist/plugins/videojs.record.ffmpeg-wasm.js"></script>

<script src="browser-workarounds.js"></script>

<style>
/* change player background color */
#myVideo {
background-color: #54a86b;
}
</style>
</head>
<body>

<video id="myVideo" playsinline class="video-js vjs-default-skin"></video>

<script>
var options = {
controls: true,
width: 320,
height: 240,
fluid: false,
bigPlayButton: false,
controlBar: {
volumePanel: false
},
plugins: {
record: {
audio: false,
video: true,
maxLength: 20,
displayMilliseconds: true,
debug: true,
convertEngine: 'ffmpeg.wasm',
convertWorkerURL: '//unpkg.com/@ffmpeg/core/dist/ffmpeg-core.js',
// convert recorded data to MP4 (and copy over audio data without encoding)
convertOptions: ['-c:v', 'libx264', '-preset', 'slow', '-crf', '22', '-c:a', 'copy', '-f', 'mp4'],
// specify output mime-type
pluginLibraryOptions: {
outputType: 'video/mp4'
}
}
}
};

// apply some workarounds for certain browsers
applyVideoWorkaround();

var player = videojs('myVideo', options, function() {
// print version information at startup
videojs.log('Using video.js', videojs.VERSION,
'with videojs-record', videojs.getPluginVersion('record'),
'and recordrtc', RecordRTC.version);
});
// error handling
player.on('deviceError', function() {
console.log('device error:', player.deviceErrorCode);
});

player.on('error', function(element, error) {
console.error(error);
});

// user clicked the record button and started recording
player.on('startRecord', function() {
console.log('started recording!');
});

// user completed recording and stream is available
player.on('finishRecord', function() {
// the blob object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished recording: ', player.recordedData);
});

// converter completed and stream is available
player.on('finishConvert', function() {
// the convertedData object contains the recorded data that
// can be downloaded by the user, stored on server etc.
console.log('finished converting: ', player.convertedData);
});
</script>
</body>
</html>
3 changes: 2 additions & 1 deletion docs/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ Optional dependencies when using other [video plugins](plugins#video):
Optional dependencies when using [converter plugins](plugins#converter):

- [ts-ebml](plugins/ts-ebml.md) - Creates seekable WebM files, by injecting metadata like duration.
- [ffmpeg.js](plugins/ffmpeg.js.md) - Run [FFmpeg](https://ffmpeg.org) in the browser and perform on-the-fly transcoding of recorded data.
- [ffmpeg.wasm](plugins/ffmpeg.wasm.md) - Run [FFmpeg](https://ffmpeg.org) in the browser and perform on-the-fly transcoding of recorded data.
- [ffmpeg.js](plugins/ffmpeg.js.md) - Deprecated FFmpeg plugin.
8 changes: 4 additions & 4 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Additional options for this plugin are:
| `videoRecorderType` | string or function | `'auto'` | Video recorder type to use. This allows you to specify an alternative recorder class, e.g. `WhammyRecorder`. Defaults to `auto` which let's recordrtc specify the best available recorder type. |
| `videoBitRate` | float | `1200` | The video bitrate in kbps (only used in webm-wasm plugin). |
| `videoFrameRate` | float | `30` | The video frame rate in frames per second (only used in webm-wasm plugin). |
| `videoWorkerURL` | string | `''` | URL for the video worker, for example: `../node_modules/webm-wasm/dist/webm-worker.js`. Currently only used for webm-wasm plugin. Use an empty string '' to disable (default). |
| `videoWorkerURL` | string | `''` | URL for the video worker, for example: `../node_modules/webm-wasm/dist/webm-worker.js`. Currently only used for the webm-wasm plugin. Use an empty string '' to disable (default). |
| `videoWebAssemblyURL` | string | `''` | URL for the video worker WebAssembly file. Use an empty string '' to disable (default). Currently only used for the webm-wasm plugin. |
| `audioEngine` | string | `'recordrtc'` | Audio recording library/plugin to use. Legal values are `recordrtc`, `libvorbis.js`, `vmsg`, `opus-recorder`, `opus-media-recorder`, `lamejs` and `recorder.js`. |
| `audioRecorderType` | string or function | `'auto'` | Audio recorder type to use. This allows you to specify an alternative recorder class, e.g. `StereoAudioRecorder`. Defaults to `auto` which let's recordrtc specify the best available recorder type. Currently this setting is only used with the `recordrtc` `audioEngine`. |
Expand All @@ -48,8 +48,8 @@ Additional options for this plugin are:
| `audioBufferUpdate` | boolean | `false` | Enables the `audioBufferUpdate` event that provides real-time `AudioBuffer` instances from the input audio device. |
| `animationFrameRate` | float | `200` | Frame rate for animated GIF (in frames per second). |
| `animationQuality` | float | `10` | Sets quality of color quantization (conversion of images to the maximum 256 colors allowed by the GIF specification). Lower values (minimum = 1) produce better colors, but slow processing significantly. The default produces good color mapping at reasonable speeds. Values greater than 20 do not yield significant improvements in speed. |
| `convertEngine` | string | `''` | Media converter library to use. Legal values are `ts-ebml` and `ffmpeg.js`. Use an empty string `''` to disable (default). Inspect the [player.convertedData](recorded-data#convert-data) object for the converted data. |
| `convertWorkerURL` | string | `''` | URL for the converter worker, for example: `/node_modules/ffmpeg.js/ffmpeg-worker-mp4.js`. Currently only used for ffmpeg.js plugin. Use an empty string '' to disable (default). |
| `convertEngine` | string | `''` | Media converter library to use. Legal values are `ts-ebml`, `ffmpeg.wasm` and `ffmpeg.js`. Use an empty string `''` to disable (default). Inspect the [player.convertedData](recorded-data#convert-data) object for the converted data. |
| `convertWorkerURL` | string | `''` | URL for the converter worker, for example: `/node_modules/ffmpeg.js/ffmpeg-worker-mp4.js`. Currently only used for ffmpeg.wasm and ffmpeg.js plugins. Use an empty string '' to disable (default). |
| `convertOptions` | array | `[]` | List of string options to pass to the convert engine. |
| `hotKeys` | boolean or function | `false` | Enable [keyboard hotkeys](hotkeys.md). Disabled by default. |
| `pluginLibraryOptions` | object | `{}` | Use this object to specify additional settings for the library used by the plugin. Currently only used in the opus-recorder and vmsg plugins. |
| `pluginLibraryOptions` | object | `{}` | Use this object to specify additional settings for the library used by the plugin. Currently only used for the ffmpeg.wasm, ffmpeg.js, opus-recorder and vmsg plugins. |
36 changes: 34 additions & 2 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"url": "git+https://github.com/collab-project/videojs-record.git"
},
"dependencies": {
"@ffmpeg/core": "^0.8.5",
"@ffmpeg/ffmpeg": "^0.9.7",
"ffmpeg.js": "^4.2.9003",
"lamejs": "^1.2.0",
"libvorbis.js": "^1.1.2",
Expand Down
3 changes: 2 additions & 1 deletion docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ following plugins:

| Plugin | Description |
| --- | --- |
| [ffmpeg.js](plugins/ffmpeg.js.md) | Run [FFmpeg](https://ffmpeg.org) in the browser and perform on-the-fly transcoding of recorded data. |
| [ffmpeg.wasm](plugins/ffmpeg.wasm.md) | Run [FFmpeg](https://ffmpeg.org) in the browser and perform on-the-fly transcoding of recorded data. |
| [ffmpeg.js](plugins/ffmpeg.js.md) | Deprecated FFmpeg plugin. |
| [ts-ebml](plugins/ts-ebml.md) | Creates seekable WebM files, by injecting metadata like duration. |

## Video
Expand Down
2 changes: 2 additions & 0 deletions docs/plugins/ffmpeg.js.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ffmpeg.js plugin

Note: this plugin is deprecated, use the [ffmpeg.wasm](ffmpeg.wasm.md) plugin instead.

[FFmpeg](https://ffmpeg.org) is the Swiss-army knife of media transcoding. This plugin allows
you to run FFmpeg in the browser and perform on-the-fly transcoding of recorded data.

Expand Down
63 changes: 63 additions & 0 deletions docs/plugins/ffmpeg.wasm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# ffmpeg.wasm plugin

[FFmpeg](https://ffmpeg.org) is the Swiss-army knife of media transcoding. This plugin allows
you to run FFmpeg in the browser and perform on-the-fly transcoding of recorded data.

This plugin uses [ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm) that provides a
Webassembly / Javascript port of FFmpeg.

## Example

- [online demo](https://collab-project.github.io/videojs-record/demo/video-only-ffmpegwasm.html)
- [demo source](https://github.com/collab-project/videojs-record/blob/master/examples/plugins/video-only-ffmpegwasm.html)

## Usage

Install the library:

```console
npm install --save @ffmpeg/ffmpeg @ffmpeg/core
```

Include the library and place it before any other scripts:

```html
<script src="@ffmpeg/ffmpeg/dist/ffmpeg.min.js"></script>
```

Import the plugin:

```javascript
import FFmpegWasmEngine from 'videojs-record/dist/plugins/videojs.record.ffmpeg-wasm.js';
```

And configure the `ffmpeg.wasm` `convertEngine`. For example:

```javascript
record: {
audio: true,
video: true,
maxLength: 20,
debug: true,
// enable ffmpeg.wasm plugin
convertEngine: 'ffmpeg.wasm',
convertWorkerURL: '../../node_modules/@ffmpeg/core/dist/ffmpeg-core.js',
// convert recorded data to MP4 (and copy over audio data without encoding)
convertOptions: ['-c:v', 'libx264', '-preset', 'slow', '-crf', '22', '-c:a', 'copy', '-f', 'mp4'],
// specify output mime-type
pluginLibraryOptions: {
outputType: 'video/mp4'
}
}
```

## Options

Options for this plugin:

| Option | Value | Description |
| --- | --- | --- |
| `convertEngine` | `ffmpeg.wasm` | Enables the plugin. |
| `convertOptions` | `['-f', 'mp3', '-codec:a', 'libmp3lame', '-qscale:a', '2']` | Array of arguments for FFmpeg. |
| `pluginLibraryOptions` | `{outputType: 'video/mp4'}` | Specify output mime-type and other options. |
| `convertWorkerURL` | `/path/to/@ffmpeg/core/dist/ffmpeg-core.js` | Specify encoding worker. |
4 changes: 2 additions & 2 deletions docs/recorded-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ player.on('finishRecord', function() {
## Save data

Use the `saveAs` method to show a 'Save as' browser dialog where the user can
choose the storage location for the recorded data. It accepts a `name` object that
choose the storage location for the recorded data. It accepts an object that
contains a mapping between the media type and the filename. For example:

```javascript
Expand Down Expand Up @@ -48,7 +48,7 @@ record: {
}
```

And listen for the `finishConvert` event. For example:
And listen for the `finishConvert` event:

```javascript
// converter ready and stream is available
Expand Down