Update documents

This commit is contained in:
Jerome Wu 2020-04-28 19:36:33 +08:00
parent b36360f16f
commit 55cbf63fb1
14 changed files with 202 additions and 244 deletions

View File

@ -36,6 +36,11 @@ Use FFmpeg directly in your browser without any backend services!!
| ---- | ------- | ----------- | | ---- | ------- | ----------- |
| Webcam | <a href="https://codepen.io/jeromewu/pen/qBBKzyW" target="_blank"><img alt="codepen" width="128px" src="https://blog.codepen.io/wp-content/uploads/2012/06/codepen-wordmark-display-inside-black@10x.png"></a> | [Link](https://github.com/ffmpegjs/ffmpeg.js/blob/master/examples/browser/webcam.html) | | Webcam | <a href="https://codepen.io/jeromewu/pen/qBBKzyW" target="_blank"><img alt="codepen" width="128px" src="https://blog.codepen.io/wp-content/uploads/2012/06/codepen-wordmark-display-inside-black@10x.png"></a> | [Link](https://github.com/ffmpegjs/ffmpeg.js/blob/master/examples/browser/webcam.html) |
## Supported Formats
- mp4 (x264)
- webm (vp8/vp9) (^0.8.0)
- mp3 (^0.8.0)
--- ---
@ -43,17 +48,16 @@ ffmpeg.js provides simple to use APIs, to transcode a video you only need few li
```javascript ```javascript
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('@ffmpeg/ffmpeg'); const { createFFmpeg } = require('@ffmpeg/ffmpeg');
const worker = createWorker(); const ffmpeg = createFFmpeg({ log: true });
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
await worker.write('test.avi', './test.avi'); await ffmpeg.write('test.avi', './test.avi');
await worker.transcode('test.avi', 'test.mp4'); await ffmpeg.transcode('test.avi', 'test.mp4');
const { data } = await worker.read('test.mp4'); fs.writeFileSync('./test.mp4', ffmpeg.read('test.mp4'));
fs.writeFileSync('./test.mp4', data); process.exit(0);
await worker.terminate();
})(); })();
``` ```
@ -63,18 +67,34 @@ const worker = createWorker();
$ npm install @ffmpeg/ffmpeg $ npm install @ffmpeg/ffmpeg
``` ```
> As we use `worker_threads` which was introduced in Node.js v10.5.0, please remember to add `--experimental-worker` if you are using Node.js v10, and you don't have to add anything if you are using Node.js v12 > As we are using the latest experimental features, you need to add few flags to run in Node.js
Or, using a script tag in the browser: ```
$ node --experimental-wasm-threads --experimental-wasm-bulk-memory transcode.js
```
Or, using a script tag in the browser (only works in Chrome):
```html ```html
<script src="https://unpkg.com/@ffmpeg/ffmpeg@0.7.0/dist/ffmpeg.min.js"></script> <script src="https://unpkg.com/@ffmpeg/ffmpeg@0.8.0/dist/ffmpeg.min.js"></script>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
... ...
</script> </script>
``` ```
## Multi-thread
Starting from v0.8.0, multithreading is enabled and you can use this feature by passing `-threads <NUM>` (`NUM` < 8 ). For built-in functions like `transcode()`, you can pass it as 3rd argument.
```javascript
// in transcode()
await ffmpeg.transcode('flame.avi', 'flame.mp4', '-threads 2');
// in run()
await ffmpeg.run('-i flame.avi -threads 2 flame.mp4');
```
## Examples ## Examples
- With React: https://github.com/ffmpegjs/react-app - With React: https://github.com/ffmpegjs/react-app
@ -93,3 +113,4 @@ Learn how to build ffmpeg.js from stories:
- [Part.4 ffmpeg.js v0.2 — Web Worker and Libx264](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-4-ffmpeg-js-v0-2-web-worker-and-libx264-d0596f1beb4e) - [Part.4 ffmpeg.js v0.2 — Web Worker and Libx264](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-4-ffmpeg-js-v0-2-web-worker-and-libx264-d0596f1beb4e)
- [Part.5 ffmpeg.js v0.3 — pre-js and live streaming](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-5-ffmpeg-js-v0-3-pre-js-and-live-streaming-c1498939a74c) - [Part.5 ffmpeg.js v0.3 — pre-js and live streaming](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-5-ffmpeg-js-v0-3-pre-js-and-live-streaming-c1498939a74c)
- [Part.6 a Deep Dive into File System](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-6-a-deep-dive-into-file-system-56eba10067ca) - [Part.6 a Deep Dive into File System](https://medium.com/@jeromewus/build-ffmpeg-webassembly-version-ffmpeg-js-part-6-a-deep-dive-into-file-system-56eba10067ca)
- [Part.7 multithreading (WIP)]()

View File

@ -1,67 +1,61 @@
# API # API
- [createWorker()](#create-worker) - [createFFmpeg()](#create-ffmpeg)
- [Worker.load](#worker-load) - [ffmpeg.load](#ffmpeg-load)
- [Worker.write](#worker-write) - [ffmpeg.write](#ffmpeg-write)
- [Worker.writeText](#worker-writeText) - [ffmpeg.writeText](#ffmpeg-writeText)
- [Worker.read](#worker-read) - [ffmpeg.read](#ffmpeg-read)
- [Worker.remove](#worker-remove) - [ffmpeg.remove](#ffmpeg-remove)
- [Worker.transcode](#worker-transcode) - [ffmpeg.transcode](#ffmpeg-transcode)
- [Worker.trim](#worker-trim) - [ffmpeg.trim](#ffmpeg-trim)
- [Worker.concatDemuxer](#worker-concatDemuxer) - [ffmpeg.concatDemuxer](#ffmpeg-concatDemuxer)
- [Worker.run](#worker-run) - [ffmpeg.run](#ffmpeg-run)
- [Worker.terminate](#worker-terminate)
--- ---
<a name="create-worker"></a> <a name="create-ffmpeg"></a>
## createWorker(options): Worker ## createFFmpeg(options): ffmpeg
createWorker is a factory function that creates a ffmpeg worker, a worker is basically a Web Worker in browser and Child Process in Node. createFFmpeg is a factory function that creates a ffmpeg instance.
**Arguments:** **Arguments:**
- `options` an object of customized options - `options` an object of customized options
- `corePath` path for ffmpeg-core.js script - `corePath` path for ffmpeg-core.js script
- `workerPath` path for downloading worker script - `log` a boolean to turn on all logs, default is `false`
- `workerBlobURL` a boolean to define whether to use Blob URL for worker script, default: true - `logger` a function to get log messages, a quick example is `({ message }) => console.log(message)`
- `logger` a function to log the progress, a quick example is `m => console.log(m)`
- `progress` a function to trace the progress, a quick example is `p => console.log(p)` - `progress` a function to trace the progress, a quick example is `p => console.log(p)`
**Examples:** **Examples:**
```javascript ```javascript
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({
corePath: "./node_modules/@ffmpeg/core/ffmpeg-core.js", corePath: "./node_modules/@ffmpeg/core/ffmpeg-core.js",
logger: m => console.log(m) log: true,
}); });
``` ```
<a name="worker-load"></a> <a name="ffmpeg-load"></a>
### Worker.load(jobId): Promise ### ffmpeg.load(): Promise
Worker.load() loads ffmpeg-core.js script (download from remote if not presented), it makes Web Worker/Child Process ready for next action. ffmpeg.load() loads ffmpeg-core.js script (download from remote if not presented), it makes WebAssembly code ready to use.
**Arguments:**
- `jobId` jobId is generated by ffmpeg.js to identify each job, but you can put your own when calling the function.
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
})(); })();
``` ```
<a name="worker-write"></a> <a name="ffmpeg-write"></a>
### Worker.write(path, data, jobId): Promise ### ffmpeg.write(path, data): Promise
Worker.write() writes data to specific path in Emscripten file system, it is an essential step before doing any other tasks. ffmpeg.write() writes data to specific path in Emscripten file system, it is an essential step before doing any other tasks.
> Currently we found an issue that you should not have parallel Worker.write() as it may cause unexpected behavior, please do it in sequential for-loop like [HERE](https://github.com/ffmpegjs/ffmpeg.js/blob/master/examples/browser/image2video.html#L36) > Currently we found an issue that you should not have parallel Worker.write() as it may cause unexpected behavior, please do it in sequential for-loop like [HERE](https://github.com/ffmpegjs/ffmpeg.js/blob/master/examples/browser/image2video.html#L36)
@ -69,139 +63,150 @@ Worker.write() writes data to specific path in Emscripten file system, it is an
- `path` path to write data to file system - `path` path to write data to file system
- `data` data to write, can be Uint8Array, URL or base64 format - `data` data to write, can be Uint8Array, URL or base64 format
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.write( await ffmpeg.write(
"flame.avi", "flame.avi",
"http://localhost:3000/tests/assets/flame.avi" "http://localhost:3000/tests/assets/flame.avi"
); );
})(); })();
``` ```
<a name="worker-writeText"></a> <a name="ffmpeg-writeText"></a>
### Worker.writeText(path, text, jobId): Promise ### ffmpeg.writeText(path, text): undefined
Worker.write() writes text data to specific path in Emscripten file system. ffmpeg.write() writes text data to specific path in Emscripten file system.
**Arguments:** **Arguments:**
- `path` path to write data to file system - `path` path to write data to file system
- `text` string to write to file - `text` string to write to file
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.write("sub.srt", "..."); ffmpeg.writeText("sub.srt", "...");
})(); })();
``` ```
<a name="worker-read"></a> <a name="ffmpeg-read"></a>
### Worker.read(path, jobId): Promise ### ffmpeg.read(path): Uint8Array
Worker.read() reads data from file system, often used to get output data after specific task. ffmpeg.read() reads data from file system, often used to get output data after specific task.
**Arguments:** **Arguments:**
- `path` path to read data from file system - `path` path to read data from file system
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
const { data } = await worker.read("output.mp4"); const data = ffmpeg.read("output.mp4");
})(); })();
``` ```
<a name="worker-remove"></a> <a name="ffmpeg-remove"></a>
### Worker.remove(path, jobId): Promise ### ffmpeg.remove(path): Promise
Worker.remove() removes files in file system, it will be better to delete unused files if you need to run ffmpeg.js multiple times. ffmpeg.remove() removes files in file system, it will be better to delete unused files if you need to run ffmpeg.js multiple times.
**Arguments:** **Arguments:**
- `path` path for file to delete - `path` path for file to delete
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.remove("output.mp4"); ffmpeg.remove("output.mp4");
})(); })();
``` ```
<a name="worker-transcode"></a> <a name="ffmpeg-ls"></a>
### Worker.transcode(input, output, options, jobId): Promise ### ffmpeg.ls(path): Promise
Worker.transcode() transcode a video file to another format. ffmpeg.ls() lists all files in specific path.
**Arguments:** **Arguments:**
- `input` input file path, the input file should be written through Worker.write() - `path` path to list
- `output` output file path, can be read with Worker.read() later
**Examples:**
```javascript
(async () => {
const dirs = ffmpeg.ls("/");
})();
```
<a name="ffmpeg-transcode"></a>
### ffmpeg.transcode(input, output, options): Promise
ffmpeg.transcode() transcode a video file to another format.
**Arguments:**
- `input` input file path, the input file should be written through ffmpeg.write()
- `output` output file path, can be read with ffmpeg.read() later
- `options` a string to add extra arguments to ffmpeg - `options` a string to add extra arguments to ffmpeg
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.transcode("flame.avi", "output.mp4", "-s 1920x1080"); await ffmpeg.transcode("flame.avi", "output.mp4", "-s 1920x1080");
})(); })();
``` ```
<a name="worker-trim"></a> <a name="ffmpeg-trim"></a>
### Worker.trim(input, output, from, to, options, jobId): Promise ### ffmpeg.trim(input, output, from, to, options): Promise
Worker.trim() trims video to specific interval. ffmpeg.trim() trims video to specific interval.
**Arguments:** **Arguments:**
- `inputPath` input file path, the input file should be written through Worker.write() - `inputPath` input file path, the input file should be written through ffmpeg.write()
- `outputPath` output file path, can be read with Worker.read() later - `outputPath` output file path, can be read with ffmpeg.read() later
- `from` start time, can be in time stamp (00:00:12.000) or seconds (12) - `from` start time, can be in time stamp (00:00:12.000) or seconds (12)
- `to` end time, rule same as above - `to` end time, rule same as above
- `options` a string to add extra arguments to ffmpeg - `options` a string to add extra arguments to ffmpeg
- `jobId` @see Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.trim("flame.avi", "output.mp4", 1, 2); await ffmpeg.trim("flame.avi", "output.mp4", 1, 2);
})(); })();
``` ```
<a name="worker-concatDemuxer"></a> <a name="ffmpeg-concatDemuxer"></a>
### Worker.concatDemuxer(input, output, options, jobId): Promise ### ffmpeg.concatDemuxer(input, output, options): Promise
Worker.concatDemuxer() concatenates multiple videos using concatDemuxer. This method won't encode the videos again. But it has its limitations. See [Concat demuxer Wiki](https://trac.ffmpeg.org/wiki/Concatenate) ffmpeg.concatDemuxer() concatenates multiple videos using concatDemuxer. This method won't encode the videos again. But it has its limitations. See [Concat demuxer Wiki](https://trac.ffmpeg.org/wiki/Concatenate)
**Arguments:** **Arguments:**
- `input` input file paths as an Array, the input files should be written through Worker.write() - `input` input file paths as an Array, the input files should be written through ffmpeg.write()
- `output` output file path, can be read with Worker.read() later - `output` output file path, can be read with ffmpeg.read() later
- `options` a string to add extra arguments to ffmpeg - `options` a string to add extra arguments to ffmpeg
- `jobId` check Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.concatDemuxer(["flame-1.avi", "flame-2.avi"], "output.mp4"); await ffmpeg.concatDemuxer(["flame-1.avi", "flame-2.avi"], "output.mp4");
})(); })();
``` ```
@ -209,39 +214,24 @@ If the input video files are the same as the output video file, you can pass an
```javascript ```javascript
(async () => { (async () => {
await worker.concatDemuxer(["flame-1.mp4", "flame-2.mp4"], "output.mp4", "-c copy"); await ffmpeg.concatDemuxer(["flame-1.mp4", "flame-2.mp4"], "output.mp4", "-c copy");
})(); })();
``` ```
<a name="worker-run"></a> <a name="ffmpeg-run"></a>
### Worker.run(args, jobId): Promise ### ffmpeg.run(args): Promise
Worker.run() is similar to FFmpeg cli tool, aims to provide maximum flexiblity for users. ffmpeg.run() is similar to FFmpeg cli tool, aims to provide maximum flexiblity for users.
**Arguments:** **Arguments:**
- `args` a string to represent arguments - `args` a string to represent arguments
- `jobId` check Worker.load()
**Examples:** **Examples:**
```javascript ```javascript
(async () => { (async () => {
await worker.run("-i flame.avi -s 1920x1080 output.mp4"); await ffmpeg.run("-i flame.avi -s 1920x1080 output.mp4");
})();
```
<a name="worker-run"></a>
### Worker.terminate(): Promise
Worker.terminate() terminates web worker / worker\_threads, after terminate(), you cannot use this worker anymore.
**Examples:**
```javascript
(async () => {
await worker.terminate();
})(); })();
``` ```

View File

@ -23,33 +23,29 @@
<input type="file" id="uploader" multiple /> <input type="file" id="uploader" multiple />
<p id="message"></p> <p id="message"></p>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: "../../node_modules/@ffmpeg/core/ffmpeg-core.js",
logger: ({ message }) => console.log(message)
});
const transcode = async ({ target: { files } }) => { const transcode = async ({ target: { files } }) => {
const message = document.getElementById("message"); const message = document.getElementById("message");
message.innerHTML = "Loading ffmpeg-core.js"; message.innerHTML = "Loading ffmpeg-core.js";
await worker.load(); await ffmpeg.load();
message.innerHTML = "Start Concating"; message.innerHTML = "Start Concating";
const inputPaths = []; const inputPaths = [];
for (const file of files) { for (const file of files) {
const { name } = file; const { name } = file;
await worker.write(name, file); await ffmpeg.write(name, file);
inputPaths.push(name); inputPaths.push(name);
} }
await worker.concatDemuxer(inputPaths, "output.mp4"); await ffmpeg.concatDemuxer(inputPaths, "output.mp4");
message.innerHTML = "Complete Concating"; message.innerHTML = "Complete Concating";
const { data } = await worker.read("output.mp4"); const data = await ffmpeg.read("output.mp4");
const video = document.getElementById("output-video"); const video = document.getElementById("output-video");
video.src = URL.createObjectURL( video.src = URL.createObjectURL(
new Blob([data.buffer], { new Blob([data.buffer], {
type: "video/mp4" type: "video/mp4"
}) })
); );
await worker.terminate();
}; };
const elm = document.getElementById("uploader"); const elm = document.getElementById("uploader");
elm.addEventListener("change", transcode); elm.addEventListener("change", transcode);

View File

@ -21,34 +21,30 @@
<p id="message"></p> <p id="message"></p>
<a href="https://github.com/ffmpegjs/ffmpeg.js/tree/master/tests/assets/triangle">Data Set</a> <a href="https://github.com/ffmpegjs/ffmpeg.js/tree/master/tests/assets/triangle">Data Set</a>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
progress: (p) => console.log(p),
});
const image2video = async () => { const image2video = async () => {
const message = document.getElementById('message'); const message = document.getElementById('message');
message.innerHTML = 'Loading ffmpeg-core.js'; message.innerHTML = 'Loading ffmpeg-core.js';
await worker.load(); await ffmpeg.load();
message.innerHTML = 'Loading data'; message.innerHTML = 'Loading data';
await worker.write('audio.ogg', '../../tests/assets/triangle/audio.ogg'); await ffmpeg.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
for (let i = 0; i < 60; i += 1) { for (let i = 0; i < 60; i += 1) {
const num = `00${i}`.slice(-3); const num = `00${i}`.slice(-3);
await worker.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`); await ffmpeg.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`);
} }
message.innerHTML = 'Start transcoding'; message.innerHTML = 'Start transcoding';
await worker.run('-framerate 30 -pattern_type glob -i /data/*.png -i /data/audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4', { output: 'out.mp4' }); await ffmpeg.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4', { output: 'out.mp4' });
const { data } = await worker.read('out.mp4'); const data = await ffmpeg.read('out.mp4');
await worker.remove('audio.ogg'); await ffmpeg.remove('audio.ogg');
for (let i = 0; i < 60; i += 1) { for (let i = 0; i < 60; i += 1) {
const num = `00${i}`.slice(-3); const num = `00${i}`.slice(-3);
await worker.remove(`tmp.${num}.png`); await ffmpeg.remove(`tmp.${num}.png`);
} }
const video = document.getElementById('output-video'); const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })); video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
await worker.terminate();
} }
const elm = document.getElementById('start-btn'); const elm = document.getElementById('start-btn');
elm.addEventListener('click', image2video); elm.addEventListener('click', image2video);

View File

@ -20,29 +20,25 @@
<input type="file" id="uploader"> <input type="file" id="uploader">
<p id="message"></p> <p id="message"></p>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
logger: ({ message }) => console.log(message),
});
const transcode = async ({ target: { files } }) => { const doRun = async ({ target: { files } }) => {
const message = document.getElementById('message'); const message = document.getElementById('message');
const { name } = files[0]; const { name } = files[0];
message.innerHTML = 'Loading ffmpeg-core.js'; message.innerHTML = 'Loading ffmpeg-core.js';
await worker.load(); await ffmpeg.load();
message.innerHTML = 'Start transcoding'; message.innerHTML = 'Start transcoding';
await worker.write(name, files[0]); await ffmpeg.write(name, files[0]);
await worker.run(`-i /data/${name} output.mp4`); await ffmpeg.run(`-i ${name} output.mp4`);
message.innerHTML = 'Complete transcoding'; message.innerHTML = 'Complete transcoding';
const { data } = await worker.read('output.mp4'); const data = ffmpeg.read('output.mp4');
const video = document.getElementById('output-video'); const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })); video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
await worker.terminate();
} }
const elm = document.getElementById('uploader'); const elm = document.getElementById('uploader');
elm.addEventListener('change', transcode); elm.addEventListener('change', doRun);
</script> </script>
</body> </body>
</html> </html>

View File

@ -20,27 +20,23 @@
<input type="file" id="uploader"> <input type="file" id="uploader">
<p id="message"></p> <p id="message"></p>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
logger: ({ message }) => console.log(message),
progress: p => console.log(p),
});
const transcode = async ({ target: { files } }) => { const transcode = async ({ target: { files } }) => {
const message = document.getElementById('message'); const message = document.getElementById('message');
const { name } = files[0]; const { name } = files[0];
message.innerHTML = 'Loading ffmpeg-core.js'; message.innerHTML = 'Loading ffmpeg-core.js';
await worker.load(); await ffmpeg.load();
await worker.write(name, files[0]); await ffmpeg.write(name, files[0]);
message.innerHTML = 'Start transcoding'; message.innerHTML = 'Start transcoding';
await worker.transcode(name, 'output.mp4'); await ffmpeg.transcode(name, 'output.mp4');
message.innerHTML = 'Complete transcoding'; message.innerHTML = 'Complete transcoding';
const { data } = await worker.read('output.mp4'); const data = ffmpeg.read('output.mp4');
ffmpeg.remove('output.mp4');
const video = document.getElementById('output-video'); const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })); video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
await worker.terminate();
} }
const elm = document.getElementById('uploader'); const elm = document.getElementById('uploader');
elm.addEventListener('change', transcode); elm.addEventListener('change', transcode);

View File

@ -20,29 +20,25 @@
<input type="file" id="uploader"> <input type="file" id="uploader">
<p id="message"></p> <p id="message"></p>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
logger: ({ message }) => console.log(message),
});
const transcode = async ({ target: { files } }) => { const trim = async ({ target: { files } }) => {
const message = document.getElementById('message'); const message = document.getElementById('message');
const { name } = files[0]; const { name } = files[0];
message.innerHTML = 'Loading ffmpeg-core.js'; message.innerHTML = 'Loading ffmpeg-core.js';
await worker.load(); await ffmpeg.load();
message.innerHTML = 'Start trimming'; message.innerHTML = 'Start trimming';
await worker.write(name, files[0]); await ffmpeg.write(name, files[0]);
await worker.trim(name, 'output.mp4', 0, 10); await ffmpeg.trim(name, 'output.mp4', 0, 10);
message.innerHTML = 'Complete trimming'; message.innerHTML = 'Complete trimming';
const { data } = await worker.read('output.mp4'); const data = ffmpeg.read('output.mp4');
const video = document.getElementById('output-video'); const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })); video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
await worker.terminate();
} }
const elm = document.getElementById('uploader'); const elm = document.getElementById('uploader');
elm.addEventListener('change', transcode); elm.addEventListener('change', trim);
</script> </script>
</body> </body>
</html> </html>

View File

@ -23,11 +23,8 @@
<button id="record" disabled>Start Recording</button> <button id="record" disabled>Start Recording</button>
<p id="message"></p> <p id="message"></p>
<script> <script>
const { createWorker } = FFmpeg; const { createFFmpeg } = FFmpeg;
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
logger: ({ message }) => console.log(message),
});
const webcam = document.getElementById('webcam'); const webcam = document.getElementById('webcam');
const recordBtn = document.getElementById('record'); const recordBtn = document.getElementById('record');
@ -60,16 +57,15 @@
const message = document.getElementById('message'); const message = document.getElementById('message');
const name = 'record.webm'; const name = 'record.webm';
message.innerHTML = 'Loading ffmpeg-core.js'; message.innerHTML = 'Loading ffmpeg-core.js';
await worker.load(); await ffmpeg.load();
message.innerHTML = 'Start transcoding'; message.innerHTML = 'Start transcoding';
await worker.write(name, webcamData); await ffmpeg.write(name, webcamData);
await worker.transcode(name, 'output.mp4'); await ffmpeg.transcode(name, 'output.mp4');
message.innerHTML = 'Complete transcoding'; message.innerHTML = 'Complete transcoding';
const { data } = await worker.read('output.mp4'); const data = ffmpeg.read('output.mp4');
const video = document.getElementById('output-video'); const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })); video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
await worker.terminate();
} }
</script> </script>
</body> </body>

View File

@ -1,17 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
logger: ({ message }) => console.log(message),
});
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
console.log('Start to concat'); await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
await worker.write('flame.avi', '../../tests/assets/flame.avi'); await ffmpeg.concatDemuxer(['flame.avi', 'flame.avi'], 'flame.mp4');
await worker.concatDemuxer(['flame.avi', 'flame.avi'], 'flame.mp4'); fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
const { data } = await worker.read('flame.mp4'); process.exit(0);
console.log('Complete concat');
fs.writeFileSync('flame.mp4', Buffer.from(data));
await worker.terminate();
})(); })();

View File

@ -1,17 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
logger: ({ message }) => console.log(message),
});
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
console.log('Start hstack'); await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
await worker.write('flame.avi', '../../tests/assets/flame.avi'); await ffmpeg.run('-i flame.avi -i flame.avi -filter_complex hstack flame.mp4');
await worker.run('-i flame.avi -i flame.avi -filter_complex hstack flame.mp4'); fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
const { data } = await worker.read('flame.mp4'); process.exit(0);
console.log('Complete hstack');
fs.writeFileSync('flame.mp4', Buffer.from(data));
await worker.terminate();
})(); })();

View File

@ -1,28 +1,21 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
progress: (p) => console.log(p),
});
(async () => { (async () => {
console.log('Loading ffmpeg-core.js'); await ffmpeg.load();
await worker.load(); await ffmpeg.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
console.log('Loading data');
await worker.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
for (let i = 0; i < 60; i += 1) { for (let i = 0; i < 60; i += 1) {
const num = `00${i}`.slice(-3); const num = `00${i}`.slice(-3);
await worker.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`); await ffmpeg.write(`tmp.${num}.png`, `../../tests/assets/triangle/tmp.${num}.png`);
} }
console.log('Start transcoding'); await ffmpeg.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4');
await worker.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4'); await ffmpeg.remove('audio.ogg');
const { data } = await worker.read('out.mp4');
console.log('Complete transcoding');
await worker.remove('audio.ogg');
for (let i = 0; i < 60; i += 1) { for (let i = 0; i < 60; i += 1) {
const num = `00${i}`.slice(-3); const num = `00${i}`.slice(-3);
await worker.remove(`tmp.${num}.png`); await ffmpeg.remove(`tmp.${num}.png`);
} }
fs.writeFileSync('out.mp4', Buffer.from(data)); fs.writeFileSync('out.mp4', ffmpeg.read('out.mp4'));
await worker.terminate(); process.exit(0);
})(); })();

View File

@ -1,17 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
logger: ({ message }) => console.log(message),
});
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
console.log('Start transcoding'); await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
await worker.write('flame.avi', '../../tests/assets/flame.avi'); await ffmpeg.run('-i flame.avi flame.mp4');
await worker.run('-i flame.avi flame.mp4'); fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
const { data } = await worker.read('flame.mp4'); process.exit(0);
console.log('Complete transcoding');
fs.writeFileSync('flame.mp4', Buffer.from(data));
await worker.terminate();
})(); })();

View File

@ -1,17 +1,15 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({
logger: ({ message }) => console.log(message), log: true,
}); });
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
console.log('Start transcoding'); await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
await worker.write('flame.avi', '../../tests/assets/flame.avi'); await ffmpeg.transcode('flame.avi', 'flame.mp4', '-threads 2');
await worker.transcode('flame.avi', 'flame.mp4'); const data = ffmpeg.read('flame.mp4');
const { data } = await worker.read('flame.mp4');
console.log('Complete transcoding');
fs.writeFileSync('flame.mp4', Buffer.from(data)); fs.writeFileSync('flame.mp4', Buffer.from(data));
await worker.terminate(); process.exit(0);
})(); })();

View File

@ -1,17 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const { createWorker } = require('../../src'); const { createFFmpeg } = require('../../src');
const worker = createWorker({ const ffmpeg = createFFmpeg({ log: true });
logger: ({ message }) => console.log(message),
});
(async () => { (async () => {
await worker.load(); await ffmpeg.load();
console.log('Start trimming'); await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
await worker.write('flame.avi', '../../tests/assets/flame.avi'); await ffmpeg.trim('flame.avi', 'flame_trim.avi', 0, 10);
await worker.trim('flame.avi', 'flame_trim.avi', 0, 10); fs.writeFileSync('flame_trim.avi', ffmpeg.read('flame_trim.avi'));
const { data } = await worker.read('flame_trim.avi'); process.exit(0);
console.log('Complete trimming');
fs.writeFileSync('flame_trim.avi', Buffer.from(data));
await worker.terminate();
})(); })();