Update documents
This commit is contained in:
parent
b36360f16f
commit
55cbf63fb1
45
README.md
45
README.md
@ -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) |
|
||||
|
||||
## 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
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('@ffmpeg/ffmpeg');
|
||||
const { createFFmpeg } = require('@ffmpeg/ffmpeg');
|
||||
|
||||
const worker = createWorker();
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
await worker.write('test.avi', './test.avi');
|
||||
await worker.transcode('test.avi', 'test.mp4');
|
||||
const { data } = await worker.read('test.mp4');
|
||||
fs.writeFileSync('./test.mp4', data);
|
||||
await worker.terminate();
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('test.avi', './test.avi');
|
||||
await ffmpeg.transcode('test.avi', 'test.mp4');
|
||||
fs.writeFileSync('./test.mp4', ffmpeg.read('test.mp4'));
|
||||
process.exit(0);
|
||||
})();
|
||||
```
|
||||
|
||||
@ -63,18 +67,34 @@ const worker = createWorker();
|
||||
$ 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
|
||||
<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>
|
||||
const { createWorker } = FFmpeg;
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
...
|
||||
</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
|
||||
|
||||
- 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.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.7 multithreading (WIP)]()
|
||||
|
168
docs/api.md
168
docs/api.md
@ -1,67 +1,61 @@
|
||||
# API
|
||||
|
||||
- [createWorker()](#create-worker)
|
||||
- [Worker.load](#worker-load)
|
||||
- [Worker.write](#worker-write)
|
||||
- [Worker.writeText](#worker-writeText)
|
||||
- [Worker.read](#worker-read)
|
||||
- [Worker.remove](#worker-remove)
|
||||
- [Worker.transcode](#worker-transcode)
|
||||
- [Worker.trim](#worker-trim)
|
||||
- [Worker.concatDemuxer](#worker-concatDemuxer)
|
||||
- [Worker.run](#worker-run)
|
||||
- [Worker.terminate](#worker-terminate)
|
||||
- [createFFmpeg()](#create-ffmpeg)
|
||||
- [ffmpeg.load](#ffmpeg-load)
|
||||
- [ffmpeg.write](#ffmpeg-write)
|
||||
- [ffmpeg.writeText](#ffmpeg-writeText)
|
||||
- [ffmpeg.read](#ffmpeg-read)
|
||||
- [ffmpeg.remove](#ffmpeg-remove)
|
||||
- [ffmpeg.transcode](#ffmpeg-transcode)
|
||||
- [ffmpeg.trim](#ffmpeg-trim)
|
||||
- [ffmpeg.concatDemuxer](#ffmpeg-concatDemuxer)
|
||||
- [ffmpeg.run](#ffmpeg-run)
|
||||
|
||||
---
|
||||
|
||||
<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:**
|
||||
|
||||
- `options` an object of customized options
|
||||
- `corePath` path for ffmpeg-core.js script
|
||||
- `workerPath` path for downloading worker script
|
||||
- `workerBlobURL` a boolean to define whether to use Blob URL for worker script, default: true
|
||||
- `logger` a function to log the progress, a quick example is `m => console.log(m)`
|
||||
- `log` a boolean to turn on all logs, default is `false`
|
||||
- `logger` a function to get log messages, a quick example is `({ message }) => console.log(message)`
|
||||
- `progress` a function to trace the progress, a quick example is `p => console.log(p)`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({
|
||||
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.
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `jobId` jobId is generated by ffmpeg.js to identify each job, but you can put your own when calling the function.
|
||||
ffmpeg.load() loads ffmpeg-core.js script (download from remote if not presented), it makes WebAssembly code ready to use.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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)
|
||||
|
||||
@ -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
|
||||
- `data` data to write, can be Uint8Array, URL or base64 format
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(async () => {
|
||||
await worker.write(
|
||||
await ffmpeg.write(
|
||||
"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:**
|
||||
|
||||
- `path` path to write data to file system
|
||||
- `text` string to write to file
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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:**
|
||||
|
||||
- `path` path to read data from file system
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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:**
|
||||
|
||||
- `path` path for file to delete
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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:**
|
||||
|
||||
- `input` input file path, the input file should be written through Worker.write()
|
||||
- `output` output file path, can be read with Worker.read() later
|
||||
- `path` path to list
|
||||
|
||||
**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
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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:**
|
||||
|
||||
- `inputPath` input file path, the input file should be written through Worker.write()
|
||||
- `outputPath` output file path, can be read with Worker.read() later
|
||||
- `inputPath` input file path, the input file should be written through ffmpeg.write()
|
||||
- `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)
|
||||
- `to` end time, rule same as above
|
||||
- `options` a string to add extra arguments to ffmpeg
|
||||
- `jobId` @see Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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:**
|
||||
|
||||
- `input` input file paths as an Array, the input files should be written through Worker.write()
|
||||
- `output` output file path, can be read with Worker.read() later
|
||||
- `input` input file paths as an Array, the input files 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
|
||||
- `jobId` check Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(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
|
||||
(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:**
|
||||
|
||||
- `args` a string to represent arguments
|
||||
- `jobId` check Worker.load()
|
||||
|
||||
**Examples:**
|
||||
|
||||
```javascript
|
||||
(async () => {
|
||||
await worker.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();
|
||||
await ffmpeg.run("-i flame.avi -s 1920x1080 output.mp4");
|
||||
})();
|
||||
```
|
||||
|
@ -23,33 +23,29 @@
|
||||
<input type="file" id="uploader" multiple />
|
||||
<p id="message"></p>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: "../../node_modules/@ffmpeg/core/ffmpeg-core.js",
|
||||
logger: ({ message }) => console.log(message)
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const message = document.getElementById("message");
|
||||
message.innerHTML = "Loading ffmpeg-core.js";
|
||||
await worker.load();
|
||||
await ffmpeg.load();
|
||||
message.innerHTML = "Start Concating";
|
||||
const inputPaths = [];
|
||||
for (const file of files) {
|
||||
const { name } = file;
|
||||
await worker.write(name, file);
|
||||
await ffmpeg.write(name, file);
|
||||
inputPaths.push(name);
|
||||
}
|
||||
await worker.concatDemuxer(inputPaths, "output.mp4");
|
||||
await ffmpeg.concatDemuxer(inputPaths, "output.mp4");
|
||||
message.innerHTML = "Complete Concating";
|
||||
const { data } = await worker.read("output.mp4");
|
||||
const data = await ffmpeg.read("output.mp4");
|
||||
const video = document.getElementById("output-video");
|
||||
video.src = URL.createObjectURL(
|
||||
new Blob([data.buffer], {
|
||||
type: "video/mp4"
|
||||
})
|
||||
);
|
||||
await worker.terminate();
|
||||
};
|
||||
const elm = document.getElementById("uploader");
|
||||
elm.addEventListener("change", transcode);
|
||||
|
@ -21,34 +21,30 @@
|
||||
<p id="message"></p>
|
||||
<a href="https://github.com/ffmpegjs/ffmpeg.js/tree/master/tests/assets/triangle">Data Set</a>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||
progress: (p) => console.log(p),
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const image2video = async () => {
|
||||
const message = document.getElementById('message');
|
||||
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||
await worker.load();
|
||||
await ffmpeg.load();
|
||||
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) {
|
||||
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';
|
||||
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' });
|
||||
const { data } = await worker.read('out.mp4');
|
||||
await worker.remove('audio.ogg');
|
||||
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 ffmpeg.read('out.mp4');
|
||||
await ffmpeg.remove('audio.ogg');
|
||||
for (let i = 0; i < 60; i += 1) {
|
||||
const num = `00${i}`.slice(-3);
|
||||
await worker.remove(`tmp.${num}.png`);
|
||||
await ffmpeg.remove(`tmp.${num}.png`);
|
||||
}
|
||||
|
||||
const video = document.getElementById('output-video');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
await worker.terminate();
|
||||
}
|
||||
const elm = document.getElementById('start-btn');
|
||||
elm.addEventListener('click', image2video);
|
||||
|
@ -20,29 +20,25 @@
|
||||
<input type="file" id="uploader">
|
||||
<p id="message"></p>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const doRun = async ({ target: { files } }) => {
|
||||
const message = document.getElementById('message');
|
||||
const { name } = files[0];
|
||||
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||
await worker.load();
|
||||
await ffmpeg.load();
|
||||
message.innerHTML = 'Start transcoding';
|
||||
await worker.write(name, files[0]);
|
||||
await worker.run(`-i /data/${name} output.mp4`);
|
||||
await ffmpeg.write(name, files[0]);
|
||||
await ffmpeg.run(`-i ${name} output.mp4`);
|
||||
message.innerHTML = 'Complete transcoding';
|
||||
const { data } = await worker.read('output.mp4');
|
||||
const data = ffmpeg.read('output.mp4');
|
||||
|
||||
const video = document.getElementById('output-video');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
await worker.terminate();
|
||||
}
|
||||
const elm = document.getElementById('uploader');
|
||||
elm.addEventListener('change', transcode);
|
||||
elm.addEventListener('change', doRun);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -20,27 +20,23 @@
|
||||
<input type="file" id="uploader">
|
||||
<p id="message"></p>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||
logger: ({ message }) => console.log(message),
|
||||
progress: p => console.log(p),
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const message = document.getElementById('message');
|
||||
const { name } = files[0];
|
||||
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||
await worker.load();
|
||||
await worker.write(name, files[0]);
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write(name, files[0]);
|
||||
message.innerHTML = 'Start transcoding';
|
||||
await worker.transcode(name, 'output.mp4');
|
||||
await ffmpeg.transcode(name, 'output.mp4');
|
||||
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');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
await worker.terminate();
|
||||
}
|
||||
const elm = document.getElementById('uploader');
|
||||
elm.addEventListener('change', transcode);
|
||||
|
@ -20,29 +20,25 @@
|
||||
<input type="file" id="uploader">
|
||||
<p id="message"></p>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const transcode = async ({ target: { files } }) => {
|
||||
const trim = async ({ target: { files } }) => {
|
||||
const message = document.getElementById('message');
|
||||
const { name } = files[0];
|
||||
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||
await worker.load();
|
||||
await ffmpeg.load();
|
||||
message.innerHTML = 'Start trimming';
|
||||
await worker.write(name, files[0]);
|
||||
await worker.trim(name, 'output.mp4', 0, 10);
|
||||
await ffmpeg.write(name, files[0]);
|
||||
await ffmpeg.trim(name, 'output.mp4', 0, 10);
|
||||
message.innerHTML = 'Complete trimming';
|
||||
const { data } = await worker.read('output.mp4');
|
||||
const data = ffmpeg.read('output.mp4');
|
||||
|
||||
const video = document.getElementById('output-video');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
await worker.terminate();
|
||||
}
|
||||
const elm = document.getElementById('uploader');
|
||||
elm.addEventListener('change', transcode);
|
||||
elm.addEventListener('change', trim);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -23,11 +23,8 @@
|
||||
<button id="record" disabled>Start Recording</button>
|
||||
<p id="message"></p>
|
||||
<script>
|
||||
const { createWorker } = FFmpeg;
|
||||
const worker = createWorker({
|
||||
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const { createFFmpeg } = FFmpeg;
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
const webcam = document.getElementById('webcam');
|
||||
const recordBtn = document.getElementById('record');
|
||||
@ -60,16 +57,15 @@
|
||||
const message = document.getElementById('message');
|
||||
const name = 'record.webm';
|
||||
message.innerHTML = 'Loading ffmpeg-core.js';
|
||||
await worker.load();
|
||||
await ffmpeg.load();
|
||||
message.innerHTML = 'Start transcoding';
|
||||
await worker.write(name, webcamData);
|
||||
await worker.transcode(name, 'output.mp4');
|
||||
await ffmpeg.write(name, webcamData);
|
||||
await ffmpeg.transcode(name, 'output.mp4');
|
||||
message.innerHTML = 'Complete transcoding';
|
||||
const { data } = await worker.read('output.mp4');
|
||||
const data = ffmpeg.read('output.mp4');
|
||||
|
||||
const video = document.getElementById('output-video');
|
||||
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
|
||||
await worker.terminate();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
@ -1,17 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
console.log('Start to concat');
|
||||
await worker.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await worker.concatDemuxer(['flame.avi', 'flame.avi'], 'flame.mp4');
|
||||
const { data } = await worker.read('flame.mp4');
|
||||
console.log('Complete concat');
|
||||
fs.writeFileSync('flame.mp4', Buffer.from(data));
|
||||
await worker.terminate();
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await ffmpeg.concatDemuxer(['flame.avi', 'flame.avi'], 'flame.mp4');
|
||||
fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
|
||||
process.exit(0);
|
||||
})();
|
||||
|
@ -1,17 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
console.log('Start hstack');
|
||||
await worker.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await worker.run('-i flame.avi -i flame.avi -filter_complex hstack flame.mp4');
|
||||
const { data } = await worker.read('flame.mp4');
|
||||
console.log('Complete hstack');
|
||||
fs.writeFileSync('flame.mp4', Buffer.from(data));
|
||||
await worker.terminate();
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await ffmpeg.run('-i flame.avi -i flame.avi -filter_complex hstack flame.mp4');
|
||||
fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
|
||||
process.exit(0);
|
||||
})();
|
||||
|
@ -1,28 +1,21 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
progress: (p) => console.log(p),
|
||||
});
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
console.log('Loading ffmpeg-core.js');
|
||||
await worker.load();
|
||||
console.log('Loading data');
|
||||
await worker.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('audio.ogg', '../../tests/assets/triangle/audio.ogg');
|
||||
for (let i = 0; i < 60; i += 1) {
|
||||
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 worker.run('-framerate 30 -pattern_type glob -i *.png -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4');
|
||||
const { data } = await worker.read('out.mp4');
|
||||
console.log('Complete transcoding');
|
||||
await worker.remove('audio.ogg');
|
||||
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 ffmpeg.remove('audio.ogg');
|
||||
for (let i = 0; i < 60; i += 1) {
|
||||
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));
|
||||
await worker.terminate();
|
||||
fs.writeFileSync('out.mp4', ffmpeg.read('out.mp4'));
|
||||
process.exit(0);
|
||||
})();
|
||||
|
@ -1,17 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
console.log('Start transcoding');
|
||||
await worker.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await worker.run('-i flame.avi flame.mp4');
|
||||
const { data } = await worker.read('flame.mp4');
|
||||
console.log('Complete transcoding');
|
||||
fs.writeFileSync('flame.mp4', Buffer.from(data));
|
||||
await worker.terminate();
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await ffmpeg.run('-i flame.avi flame.mp4');
|
||||
fs.writeFileSync('flame.mp4', ffmpeg.read('flame.mp4'));
|
||||
process.exit(0);
|
||||
})();
|
||||
|
@ -1,17 +1,15 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
logger: ({ message }) => console.log(message),
|
||||
const ffmpeg = createFFmpeg({
|
||||
log: true,
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
console.log('Start transcoding');
|
||||
await worker.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await worker.transcode('flame.avi', 'flame.mp4');
|
||||
const { data } = await worker.read('flame.mp4');
|
||||
console.log('Complete transcoding');
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await ffmpeg.transcode('flame.avi', 'flame.mp4', '-threads 2');
|
||||
const data = ffmpeg.read('flame.mp4');
|
||||
fs.writeFileSync('flame.mp4', Buffer.from(data));
|
||||
await worker.terminate();
|
||||
process.exit(0);
|
||||
})();
|
||||
|
@ -1,17 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const { createWorker } = require('../../src');
|
||||
const { createFFmpeg } = require('../../src');
|
||||
|
||||
const worker = createWorker({
|
||||
logger: ({ message }) => console.log(message),
|
||||
});
|
||||
const ffmpeg = createFFmpeg({ log: true });
|
||||
|
||||
(async () => {
|
||||
await worker.load();
|
||||
console.log('Start trimming');
|
||||
await worker.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await worker.trim('flame.avi', 'flame_trim.avi', 0, 10);
|
||||
const { data } = await worker.read('flame_trim.avi');
|
||||
console.log('Complete trimming');
|
||||
fs.writeFileSync('flame_trim.avi', Buffer.from(data));
|
||||
await worker.terminate();
|
||||
await ffmpeg.load();
|
||||
await ffmpeg.write('flame.avi', '../../tests/assets/flame.avi');
|
||||
await ffmpeg.trim('flame.avi', 'flame_trim.avi', 0, 10);
|
||||
fs.writeFileSync('flame_trim.avi', ffmpeg.read('flame_trim.avi'));
|
||||
process.exit(0);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user