diff --git a/CHANGES.md b/CHANGES.md index dcfd83ade..8f46ec290 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## 4.7.0 - unreleased - Fix video.js v8 deprecation warnings +- ffmpeg.wasm plugin: add support for v0.12.x - Bump required version for: - webrtc-adapter (8.2.3 or newer) diff --git a/docs/demo/animated-gif.html b/docs/demo/animated-gif.html index e5eee98f7..c5cd69d18 100644 --- a/docs/demo/animated-gif.html +++ b/docs/demo/animated-gif.html @@ -4,11 +4,11 @@ Animated GIF Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-ffmpegjs.html b/docs/demo/audio-only-ffmpegjs.html index 4e7569c1b..bd49778cb 100644 --- a/docs/demo/audio-only-ffmpegjs.html +++ b/docs/demo/audio-only-ffmpegjs.html @@ -4,12 +4,12 @@ ffmpeg.js Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-lamejs.html b/docs/demo/audio-only-lamejs.html index 7c9cf0305..e6be8a3b8 100644 --- a/docs/demo/audio-only-lamejs.html +++ b/docs/demo/audio-only-lamejs.html @@ -4,12 +4,12 @@ Lamejs Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-mp3.html b/docs/demo/audio-only-mp3.html index 658e3f9bc..386bc2895 100644 --- a/docs/demo/audio-only-mp3.html +++ b/docs/demo/audio-only-mp3.html @@ -4,12 +4,12 @@ vmsg Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-ogg.html b/docs/demo/audio-only-ogg.html index b6d0977ae..64c5bc1a6 100644 --- a/docs/demo/audio-only-ogg.html +++ b/docs/demo/audio-only-ogg.html @@ -4,12 +4,12 @@ Libvorbis Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-opus-media-recorder.html b/docs/demo/audio-only-opus-media-recorder.html index 75091efbb..08b0b178b 100644 --- a/docs/demo/audio-only-opus-media-recorder.html +++ b/docs/demo/audio-only-opus-media-recorder.html @@ -4,12 +4,12 @@ opus-media-recorder Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-opus.html b/docs/demo/audio-only-opus.html index b089ea0d9..cbb3a207a 100644 --- a/docs/demo/audio-only-opus.html +++ b/docs/demo/audio-only-opus.html @@ -4,12 +4,12 @@ Opus-recorder Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only-recorderjs.html b/docs/demo/audio-only-recorderjs.html index 29298c4cc..eff2bd32f 100644 --- a/docs/demo/audio-only-recorderjs.html +++ b/docs/demo/audio-only-recorderjs.html @@ -4,12 +4,12 @@ Recorder.js Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-only.html b/docs/demo/audio-only.html index b4951f7cf..f918624d7 100644 --- a/docs/demo/audio-only.html +++ b/docs/demo/audio-only.html @@ -4,12 +4,12 @@ Audio-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-screen.html b/docs/demo/audio-screen.html index 13f948d9c..bf2e417e9 100644 --- a/docs/demo/audio-screen.html +++ b/docs/demo/audio-screen.html @@ -4,11 +4,11 @@ Audio/Screen Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/audio-video.html b/docs/demo/audio-video.html index d7c878289..ae58b89de 100644 --- a/docs/demo/audio-video.html +++ b/docs/demo/audio-video.html @@ -4,11 +4,11 @@ Audio/Video Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/change-audio-input.html b/docs/demo/change-audio-input.html index 4552f2a2d..34b86a1d5 100644 --- a/docs/demo/change-audio-input.html +++ b/docs/demo/change-audio-input.html @@ -4,12 +4,12 @@ Audio Input Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/change-audio-output.html b/docs/demo/change-audio-output.html index ead21dd2a..beddd508f 100644 --- a/docs/demo/change-audio-output.html +++ b/docs/demo/change-audio-output.html @@ -4,12 +4,12 @@ Audio Output Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/change-video-input.html b/docs/demo/change-video-input.html index e3a753205..68a6b826b 100644 --- a/docs/demo/change-video-input.html +++ b/docs/demo/change-video-input.html @@ -4,11 +4,11 @@ Video Input Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/enumerate-devices.html b/docs/demo/enumerate-devices.html index de89e7f75..e6195208d 100644 --- a/docs/demo/enumerate-devices.html +++ b/docs/demo/enumerate-devices.html @@ -4,12 +4,12 @@ Enumerate Devices Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/hot-keys.html b/docs/demo/hot-keys.html index 5664a810c..e17e83a89 100644 --- a/docs/demo/hot-keys.html +++ b/docs/demo/hot-keys.html @@ -4,11 +4,11 @@ Hot-keys Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/image-only.html b/docs/demo/image-only.html index ca31def3a..63ee2ad76 100644 --- a/docs/demo/image-only.html +++ b/docs/demo/image-only.html @@ -4,11 +4,11 @@ Image-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/multi.html b/docs/demo/multi.html index ae0f81942..f65c5549e 100644 --- a/docs/demo/multi.html +++ b/docs/demo/multi.html @@ -4,11 +4,11 @@ Multiple recorders and player on page - Record Plugin for Video.js - + - + diff --git a/docs/demo/picture-in-picture.html b/docs/demo/picture-in-picture.html index 005f88d3c..4715e5873 100644 --- a/docs/demo/picture-in-picture.html +++ b/docs/demo/picture-in-picture.html @@ -4,11 +4,11 @@ Picture-in-Picture - Record Plugin for Video.js - + - + diff --git a/docs/demo/react/index.html b/docs/demo/react/index.html index b8977ba16..5abb50a2f 100644 --- a/docs/demo/react/index.html +++ b/docs/demo/react/index.html @@ -8,11 +8,11 @@ - + - + diff --git a/docs/demo/screen-only.html b/docs/demo/screen-only.html index 0995504b9..94b781dde 100644 --- a/docs/demo/screen-only.html +++ b/docs/demo/screen-only.html @@ -4,11 +4,11 @@ Screen-only Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/timeslice.html b/docs/demo/timeslice.html index a9e249fb9..9df25b566 100644 --- a/docs/demo/timeslice.html +++ b/docs/demo/timeslice.html @@ -4,11 +4,11 @@ timeSlice Example - Record Plugin for Video.js - + - + diff --git a/docs/demo/video-only-ebml.html b/docs/demo/video-only-ebml.html index 504286d63..397b018f0 100644 --- a/docs/demo/video-only-ebml.html +++ b/docs/demo/video-only-ebml.html @@ -4,11 +4,11 @@ ts-ebml video-only example - Record Plugin for Video.js - + - + diff --git a/docs/demo/video-only-ffmpegwasm.html b/docs/demo/video-only-ffmpegwasm.html index 40eeb47ca..e957c5642 100644 --- a/docs/demo/video-only-ffmpegwasm.html +++ b/docs/demo/video-only-ffmpegwasm.html @@ -4,14 +4,15 @@ ffmpeg.wasm video-only example - Record Plugin for Video.js - + - + - + + @@ -47,9 +48,12 @@ displayMilliseconds: true, debug: true, convertEngine: 'ffmpeg.wasm', - convertWorkerURL: '//unpkg.com/@ffmpeg/core/dist/ffmpeg-core.js', + // multi-threaded worker + coreURL: '//unpkg.com/@ffmpeg/core-mt/dist/umd/ffmpeg-core.js', + convertWorkerURL: '//unpkg.com/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js', + audioWebAssemblyURL: '//unpkg.com/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm', // 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'], + convertOptions: ['-c:v', 'libx264', '-crf', '22', '-c:a', 'copy', '-f', 'mp4'], // specify output mime-type pluginLibraryOptions: { outputType: 'video/mp4' diff --git a/docs/demo/video-only-webm-wasm.html b/docs/demo/video-only-webm-wasm.html index 2235a2772..ffd456198 100644 --- a/docs/demo/video-only-webm-wasm.html +++ b/docs/demo/video-only-webm-wasm.html @@ -4,14 +4,14 @@ webm-wasm video-only example - Record Plugin for Video.js - + - + diff --git a/docs/demo/video-only.html b/docs/demo/video-only.html index 1aa9b4c2c..36bccf374 100644 --- a/docs/demo/video-only.html +++ b/docs/demo/video-only.html @@ -4,11 +4,11 @@ Video-only Example - Record Plugin for Video.js - + - + diff --git a/docs/options.md b/docs/options.md index f7e372641..37211c088 100644 --- a/docs/options.md +++ b/docs/options.md @@ -45,7 +45,7 @@ Additional options for this plugin are: | `audioBitRate` | float | `128` | The audio bitrate in kbps (only used in the lamejs plugin). | | `audioChannels` | float | `2` | Number of audio channels. Using a single channel results in a smaller file size. | | `audioWorkerURL` | string | `''` | URL for the audio worker, for example: `/opus-recorder/build/encoderWorker.min.js`. Currently only used for opus-recorder, opus-media-recorder and lamejs plugins. Use an empty string '' to disable (default). | -| `audioWebAssemblyURL` | string | `''` | URL for the audio worker WebAssembly file. Use an empty string '' to disable (default). Currently only used for the vmsg and opus-media-recorder plugins. | +| `audioWebAssemblyURL` | string | `''` | URL for the audio worker WebAssembly file. Use an empty string '' to disable (default). Currently only used for the vmsg, ffmpeg.wasm and opus-media-recorder plugins. | | `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. | diff --git a/docs/package-lock.json b/docs/package-lock.json index 10248d511..f1bbd4a29 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9,8 +9,10 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@ffmpeg/core": "^0.12.2", - "@ffmpeg/ffmpeg": "^0.11.6", + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/core-mt": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", + "@ffmpeg/util": "^0.12.1", "ffmpeg.js": "^4.2.9003", "lamejs": "^1.2.1", "libvorbis.js": "^1.1.2", @@ -29,31 +31,47 @@ } }, "node_modules/@ffmpeg/core": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.2.tgz", - "integrity": "sha512-UnzHvuNFbzmVZERSDtWGQvna01eKMfOWGG6SUn+s8mnKm5aH2zcrEIMgOMYpc6yJqrdRt0LBtT3ijF65rWlxIA==", + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", + "integrity": "sha512-PrjWBTfGn2WVn9T7wGnzfFwChbqWeZc7tM9vvJZVRadYFUDakfzy7W0LpYC0cvvK0xT82qlBsk38lQhJ/Hps5A==", + "engines": { + "node": ">=16.x" + } + }, + "node_modules/@ffmpeg/core-mt": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core-mt/-/core-mt-0.12.6.tgz", + "integrity": "sha512-f7wrOeUk24VFRi2Gfsp/mwwkK1hbDV0ajgm2fOU/oRi+IDullyzAYdHOagAWfpSZXcTPAGZ1Ild7HmBwr3k2tg==", "engines": { - "node": ">=16.6.0" + "node": ">=16.x" } }, "node_modules/@ffmpeg/ffmpeg": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz", - "integrity": "sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA==", + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", "dependencies": { - "is-url": "^1.2.4", - "node-fetch": "^2.6.1", - "regenerator-runtime": "^0.13.7", - "resolve-url": "^0.2.1" + "@ffmpeg/types": "^0.12.2" }, "engines": { - "node": ">=12.16.1" + "node": ">=18.x" + } + }, + "node_modules/@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", + "engines": { + "node": ">=16.x" } }, - "node_modules/@ffmpeg/ffmpeg/node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + "node_modules/@ffmpeg/util": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", + "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==", + "engines": { + "node": ">=18.x" + } }, "node_modules/@sindresorhus/is": { "version": "0.14.0", @@ -1504,11 +1522,6 @@ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, "node_modules/is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -1781,6 +1794,7 @@ "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -2482,12 +2496,6 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "dev": true }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -2902,7 +2910,8 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true }, "node_modules/tweezer.js": { "version": "1.5.0", @@ -3111,7 +3120,8 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true }, "node_modules/webm-wasm": { "version": "0.4.1", @@ -3122,6 +3132,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3375,28 +3386,33 @@ }, "dependencies": { "@ffmpeg/core": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.2.tgz", - "integrity": "sha512-UnzHvuNFbzmVZERSDtWGQvna01eKMfOWGG6SUn+s8mnKm5aH2zcrEIMgOMYpc6yJqrdRt0LBtT3ijF65rWlxIA==" + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", + "integrity": "sha512-PrjWBTfGn2WVn9T7wGnzfFwChbqWeZc7tM9vvJZVRadYFUDakfzy7W0LpYC0cvvK0xT82qlBsk38lQhJ/Hps5A==" + }, + "@ffmpeg/core-mt": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core-mt/-/core-mt-0.12.6.tgz", + "integrity": "sha512-f7wrOeUk24VFRi2Gfsp/mwwkK1hbDV0ajgm2fOU/oRi+IDullyzAYdHOagAWfpSZXcTPAGZ1Ild7HmBwr3k2tg==" }, "@ffmpeg/ffmpeg": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz", - "integrity": "sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA==", + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", "requires": { - "is-url": "^1.2.4", - "node-fetch": "^2.6.1", - "regenerator-runtime": "^0.13.7", - "resolve-url": "^0.2.1" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - } + "@ffmpeg/types": "^0.12.2" } }, + "@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==" + }, + "@ffmpeg/util": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", + "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -4503,11 +4519,6 @@ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -4728,6 +4739,7 @@ "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, "requires": { "whatwg-url": "^5.0.0" } @@ -5259,11 +5271,6 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -5594,7 +5601,8 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true }, "tweezer.js": { "version": "1.5.0", @@ -5760,7 +5768,8 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true }, "webm-wasm": { "version": "0.4.1", @@ -5771,6 +5780,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/docs/package.json b/docs/package.json index fd2885f34..d17954d74 100644 --- a/docs/package.json +++ b/docs/package.json @@ -30,8 +30,10 @@ "url": "git+https://github.com/collab-project/videojs-record.git" }, "dependencies": { - "@ffmpeg/core": "^0.12.2", - "@ffmpeg/ffmpeg": "^0.11.6", + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/core-mt": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", + "@ffmpeg/util": "^0.12.1", "ffmpeg.js": "^4.2.9003", "lamejs": "^1.2.1", "libvorbis.js": "^1.1.2", diff --git a/docs/plugins/ffmpeg.wasm.md b/docs/plugins/ffmpeg.wasm.md index baea13698..f6c5205aa 100644 --- a/docs/plugins/ffmpeg.wasm.md +++ b/docs/plugins/ffmpeg.wasm.md @@ -16,13 +16,14 @@ Webassembly / Javascript port of FFmpeg. Install the library: ```console -npm install --save @ffmpeg/ffmpeg @ffmpeg/core +npm install --save @ffmpeg/ffmpeg @ffmpeg/core @ffmpeg/core-mt @ffmpeg/util ``` -Include the library and place it before any other scripts: +Include the library files and place them before any other scripts: ```html - + + ``` Import the plugin: @@ -41,7 +42,10 @@ record: { debug: true, // enable ffmpeg.wasm plugin convertEngine: 'ffmpeg.wasm', - convertWorkerURL: '../../node_modules/@ffmpeg/core/dist/ffmpeg-core.js', + // multi-threaded worker + coreURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.js', + convertWorkerURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js', + audioWebAssemblyURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm', // 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 @@ -58,6 +62,8 @@ 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. | +| `convertOptions` | Example: `['-f', 'mp3', '-codec:a', 'libmp3lame', '-qscale:a', '2']` | Array of arguments for FFmpeg. | +| `pluginLibraryOptions` | Example: `{outputType: 'video/mp4'}` | Specify output mime-type and other options. | +| `coreURL` | `/path/to/@ffmpeg/core-mt/dist/umd/ffmpeg-core.js` | Specify ffmpeg-core main file. | +| `convertWorkerURL` | `/path/to/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js` | Specify ffmpeg-core worker. | +| `audioWebAssemblyURL` | `/path/to/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm` | Specify ffmpeg-core WebAssembly file. | diff --git a/docs/tools/update-videojs.js b/docs/tools/update-videojs.js index 9bf5eceab..bf83447c1 100644 --- a/docs/tools/update-videojs.js +++ b/docs/tools/update-videojs.js @@ -5,8 +5,8 @@ const path = require('path'); const replace = require('replace-in-file'); -const OLD_VERSION = "video.js@7.20.1"; -const NEW_VERSION = "video.js@7.21.1"; +const OLD_VERSION = "video.js@7.21.1"; +const NEW_VERSION = "video.js@8.10.0"; const options = { files: path.resolve(__dirname, '..', 'demo') + '/**/*.html', diff --git a/examples/plugins/video-only-ffmpegwasm.html b/examples/plugins/video-only-ffmpegwasm.html index 85b1b91c4..43eeb58e8 100644 --- a/examples/plugins/video-only-ffmpegwasm.html +++ b/examples/plugins/video-only-ffmpegwasm.html @@ -11,7 +11,8 @@ - + + @@ -48,9 +49,12 @@ debug: true, displayMilliseconds: false, convertEngine: 'ffmpeg.wasm', - convertWorkerURL: 'http://localhost:8080/node_modules/@ffmpeg/core/dist/ffmpeg-core.js', + // multi-threaded worker + coreURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.js', + convertWorkerURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js', + audioWebAssemblyURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm', // 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'], + convertOptions: ['-c:v', 'libx264', '-crf', '22', '-c:a', 'copy', '-f', 'mp4'], // specify output mime-type pluginLibraryOptions: { outputType: 'video/mp4' diff --git a/package-lock.json b/package-lock.json index c8873a183..1aa670ec0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,10 @@ "@babel/preset-env": "^7.23.9", "@babel/register": "^7.23.7", "@chiragrupani/karma-chromium-edge-launcher": "^2.3.1", - "@ffmpeg/core": "^0.11.0", - "@ffmpeg/ffmpeg": "^0.11.6", + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/core-mt": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", + "@ffmpeg/util": "^0.12.1", "@mattiasbuelens/web-streams-polyfill": "^0.3.2", "add-zero": "^1.0.0", "babel-loader": "^9.1.3", @@ -2095,40 +2097,52 @@ } }, "node_modules/@ffmpeg/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.11.0.tgz", - "integrity": "sha512-9Tt/+2PMpkGPXUK8n6He9G8Y+qR6qmCPSCw9iEKZxHHOvJ9BE/r0Fccj+YgDZTlyu6rXxc9x6EqCaFBIt7qzjA==", - "dev": true + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", + "integrity": "sha512-PrjWBTfGn2WVn9T7wGnzfFwChbqWeZc7tM9vvJZVRadYFUDakfzy7W0LpYC0cvvK0xT82qlBsk38lQhJ/Hps5A==", + "dev": true, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/@ffmpeg/core-mt": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core-mt/-/core-mt-0.12.6.tgz", + "integrity": "sha512-f7wrOeUk24VFRi2Gfsp/mwwkK1hbDV0ajgm2fOU/oRi+IDullyzAYdHOagAWfpSZXcTPAGZ1Ild7HmBwr3k2tg==", + "dev": true, + "engines": { + "node": ">=16.x" + } }, "node_modules/@ffmpeg/ffmpeg": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz", - "integrity": "sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA==", + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", "dev": true, "dependencies": { - "is-url": "^1.2.4", - "node-fetch": "^2.6.1", - "regenerator-runtime": "^0.13.7", - "resolve-url": "^0.2.1" + "@ffmpeg/types": "^0.12.2" }, "engines": { - "node": ">=12.16.1" + "node": ">=18.x" } }, - "node_modules/@ffmpeg/ffmpeg/node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "node_modules/@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", "dev": true, "engines": { - "node": "4.x || >=6.0.0" + "node": ">=16.x" } }, - "node_modules/@ffmpeg/ffmpeg/node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "node_modules/@ffmpeg/util": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", + "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==", + "dev": true, + "engines": { + "node": ">=18.x" + } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", @@ -9684,12 +9698,6 @@ "dev": true, "optional": true }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -18117,37 +18125,38 @@ "dev": true }, "@ffmpeg/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.11.0.tgz", - "integrity": "sha512-9Tt/+2PMpkGPXUK8n6He9G8Y+qR6qmCPSCw9iEKZxHHOvJ9BE/r0Fccj+YgDZTlyu6rXxc9x6EqCaFBIt7qzjA==", + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", + "integrity": "sha512-PrjWBTfGn2WVn9T7wGnzfFwChbqWeZc7tM9vvJZVRadYFUDakfzy7W0LpYC0cvvK0xT82qlBsk38lQhJ/Hps5A==", + "dev": true + }, + "@ffmpeg/core-mt": { + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/@ffmpeg/core-mt/-/core-mt-0.12.6.tgz", + "integrity": "sha512-f7wrOeUk24VFRi2Gfsp/mwwkK1hbDV0ajgm2fOU/oRi+IDullyzAYdHOagAWfpSZXcTPAGZ1Ild7HmBwr3k2tg==", "dev": true }, "@ffmpeg/ffmpeg": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz", - "integrity": "sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA==", + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", "dev": true, "requires": { - "is-url": "^1.2.4", - "node-fetch": "^2.6.1", - "regenerator-runtime": "^0.13.7", - "resolve-url": "^0.2.1" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - } + "@ffmpeg/types": "^0.12.2" } }, + "@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", + "dev": true + }, + "@ffmpeg/util": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", + "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==", + "dev": true + }, "@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -23999,12 +24008,6 @@ "dev": true, "optional": true }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", diff --git a/package.json b/package.json index 491e142c9..f83c7fee5 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,10 @@ "@babel/preset-env": "^7.23.9", "@babel/register": "^7.23.7", "@chiragrupani/karma-chromium-edge-launcher": "^2.3.1", - "@ffmpeg/core": "^0.11.0", - "@ffmpeg/ffmpeg": "^0.11.6", + "@ffmpeg/core": "^0.12.6", + "@ffmpeg/core-mt": "^0.12.6", + "@ffmpeg/ffmpeg": "^0.12.10", + "@ffmpeg/util": "^0.12.1", "@mattiasbuelens/web-streams-polyfill": "^0.3.2", "add-zero": "^1.0.0", "babel-loader": "^9.1.3", diff --git a/src/js/plugins/ffmpeg-wasm-plugin.js b/src/js/plugins/ffmpeg-wasm-plugin.js index 29d89b295..c0775ccac 100644 --- a/src/js/plugins/ffmpeg-wasm-plugin.js +++ b/src/js/plugins/ffmpeg-wasm-plugin.js @@ -1,3 +1,4 @@ +/* eslint no-console: ["error", { allow: ["warn", "error", "log"] }] */ /** * @file ffmpeg-wasm-plugin.js * @since 4.2.0 @@ -37,7 +38,19 @@ class FFmpegWasmEngine extends ConvertEngine { * * @type {string} */ - this.convertWorkerURL = './node_modules/@ffmpeg/core/dist/ffmpeg-core.js'; + this.coreURL = '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.js'; + /** + * Path to script `ffmpeg-core.worker.js`. + * + * @type {string} + */ + this.convertWorkerURL = '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js'; + /** + * Path to script `ffmpeg-core.wasm`. + * + * @type {string} + */ + this.audioWebAssemblyURL = '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm'; /** * Mime-type for output. * @@ -50,6 +63,8 @@ class FFmpegWasmEngine extends ConvertEngine { * @type {object} */ this.pluginLibraryOptions = {}; + + this.ffmpeg = null; } /** @@ -64,11 +79,25 @@ class FFmpegWasmEngine extends ConvertEngine { } this.outputType = this.pluginLibraryOptions.outputType; - const {version, createFFmpeg, fetchFile} = FFmpeg; - const ffmpeg = createFFmpeg({ - corePath: this.convertWorkerURL, - log: this.debug - }); + // setup ffmpeg.wasm + const {fetchFile} = FFmpegUtil; + const {FFmpeg} = FFmpegWASM; + if (this.ffmpeg === null) { + this.ffmpeg = new FFmpeg(); + + if (this.debug) { + this.ffmpeg.on('log', ({message}) => { + console.log(message); + }); + } + + await this.ffmpeg.load({ + coreURL: this.coreURL, + wasmURL: this.audioWebAssemblyURL, + workerURL: this.convertWorkerURL, + }); + } + // save timestamp const timestamp = new Date(); timestamp.setTime(data.lastModified); @@ -86,10 +115,10 @@ class FFmpegWasmEngine extends ConvertEngine { this.player().trigger('startConvert'); // load and convert blob - await ffmpeg.load(); - ffmpeg.FS('writeFile', tempInputName, await fetchFile(data)); - await ffmpeg.run(...opts); - const output = ffmpeg.FS('readFile', tempOutputName); + await this.ffmpeg.writeFile(tempInputName, await fetchFile(data)); + console.log(opts); + await this.ffmpeg.exec(opts); + const output = await this.ffmpeg.readFile(tempOutputName); // create new blob let result = new Blob([output.buffer], {type: this.outputType});