concatDemuxer implemented

This commit is contained in:
santosh898 2019-12-16 15:30:44 +05:30
parent f93ae84794
commit 68fd03d55d
4 changed files with 60 additions and 70 deletions

View File

@ -1,5 +1,4 @@
API # API
===
- [createWorker()](#create-worker) - [createWorker()](#create-worker)
- [Worker.load](#worker-load) - [Worker.load](#worker-load)
@ -14,6 +13,7 @@ API
--- ---
<a name="create-worker"></a> <a name="create-worker"></a>
## createWorker(options): Worker ## createWorker(options): Worker
createWorker is a factory function that creates a ffmpeg worker, a worker is basically a Web Worker in browser and Child Process in Node. createWorker is a factory function that creates a ffmpeg worker, a worker is basically a Web Worker in browser and Child Process in Node.
@ -27,17 +27,18 @@ createWorker is a factory function that creates a ffmpeg worker, a worker is bas
- `logger` a function to log the progress, a quick example is `m => console.log(m)` - `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 { createWorker } = FFmpeg;
const worker = createWorker({ const worker = createWorker({
corePath: './node_modules/@ffmpeg/core/ffmpeg-core.js', corePath: "./node_modules/@ffmpeg/core/ffmpeg-core.js",
logger: m => console.log(m), logger: m => console.log(m)
}); });
``` ```
<a name="worker-load"></a> <a name="worker-load"></a>
### Worker.load(jobId): Promise ### Worker.load(jobId): Promise
Worker.load() loads ffmpeg-core.js script (download from remote if not presented), it makes Web Worker/Child Process ready for next action. Worker.load() loads ffmpeg-core.js script (download from remote if not presented), it makes Web Worker/Child Process ready for next action.
@ -55,6 +56,7 @@ Worker.load() loads ffmpeg-core.js script (download from remote if not presented
``` ```
<a name="worker-write"></a> <a name="worker-write"></a>
### Worker.write(path, data): Promise ### Worker.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. Worker.write() writes data to specific path in Emscripten file system, it is an essential step before doing any other tasks.
@ -68,11 +70,15 @@ Worker.write() writes data to specific path in Emscripten file system, it is an
```javascript ```javascript
(async () => { (async () => {
await worker.write('flame.avi', 'http://localhost:3000/tests/assets/flame.avi'); await worker.write(
"flame.avi",
"http://localhost:3000/tests/assets/flame.avi"
);
})(); })();
``` ```
<a name="worker-writeText"></a> <a name="worker-writeText"></a>
### Worker.writeText(path, text): Promise ### Worker.writeText(path, text): Promise
Worker.write() writes text data to specific path in Emscripten file system. Worker.write() writes text data to specific path in Emscripten file system.
@ -86,11 +92,12 @@ Worker.write() writes text data to specific path in Emscripten file system.
```javascript ```javascript
(async () => { (async () => {
await worker.write('sub.srt', '...'); await worker.write("sub.srt", "...");
})(); })();
``` ```
<a name="worker-read"></a> <a name="worker-read"></a>
### Worker.read(path, del): Promise ### Worker.read(path, del): Promise
Worker.read() reads data from file system, often used to get output data after specific task. Worker.read() reads data from file system, often used to get output data after specific task.
@ -104,11 +111,12 @@ Worker.read() reads data from file system, often used to get output data after s
```javascript ```javascript
(async () => { (async () => {
const { data } = await worker.read('output.mp4'); const { data } = await worker.read("output.mp4");
})(); })();
``` ```
<a name="worker-remove"></a> <a name="worker-remove"></a>
### Worker.remove(path): Promise ### Worker.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. Worker.remove() removes files in file system, it will be better to delete unused files if you need to run ffmpeg.js multiple times.
@ -121,11 +129,12 @@ Worker.remove() removes files in file system, it will be better to delete unused
```javascript ```javascript
(async () => { (async () => {
await worker.remove('output.mp4'); await worker.remove("output.mp4");
})(); })();
``` ```
<a name="worker-transcode"></a> <a name="worker-transcode"></a>
### Worker.transcode(inputPath, outputPath, options, del, jobId): Promise ### Worker.transcode(inputPath, outputPath, options, del, jobId): Promise
Worker.transcode() transcode a video file to another format. Worker.transcode() transcode a video file to another format.
@ -142,11 +151,12 @@ Worker.transcode() transcode a video file to another format.
```javascript ```javascript
(async () => { (async () => {
await worker.transcode('flame.avi', 'output.mp4', '-s 1920x1080'); await worker.transcode("flame.avi", "output.mp4", "-s 1920x1080");
})(); })();
``` ```
<a name="worker-trim"></a> <a name="worker-trim"></a>
### Worker.trim(inputPath, outputPath, from, to, options, del, jobId): Promise ### Worker.trim(inputPath, outputPath, from, to, options, del, jobId): Promise
Worker.trim() trims video to specific interval. Worker.trim() trims video to specific interval.
@ -165,11 +175,34 @@ Worker.trim() trims video to specific interval.
```javascript ```javascript
(async () => { (async () => {
await worker.trim('flame.avi', 'output.mp4', 1, 2); await worker.trim("flame.avi", "output.mp4", 1, 2);
})();
```
<a name="worker-concatDemuxer"></a>
### Worker.concatDemuxer(inputPaths, outputPath, options, del, jobId): 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)
**Arguments:**
- `inputPaths` input file paths as an Array, the input files should be written through Worker.write()
- `outputPath` output file path, can be read with Worker.read() later
- `options` a string to add extra arguments to ffmpeg
- `del` a boolean to determine whether to delete input file after the task is done, default: true
- `jobId` check Worker.load()
**Examples:**
```javascript
(async () => {
await worker.trim(["flame-1.avi", "flame-2.avi"], "output.mp4");
})(); })();
``` ```
<a name="worker-run"></a> <a name="worker-run"></a>
### Worker.run(args, options, jobId): Promise ### Worker.run(args, options, jobId): Promise
Worker.run() is similar to FFmpeg cli tool, aims to provide maximum flexiblity for users. Worker.run() is similar to FFmpeg cli tool, aims to provide maximum flexiblity for users.
@ -184,6 +217,9 @@ Worker.run() is similar to FFmpeg cli tool, aims to provide maximum flexiblity f
```javascript ```javascript
(async () => { (async () => {
await worker.run('-i /data/flame.avi -s 1920x1080 output.mp4', { inputPath: 'flame.avi', outputPath: 'output.mp4' }); await worker.run("-i /data/flame.avi -s 1920x1080 output.mp4", {
inputPath: "flame.avi",
outputPath: "output.mp4"
});
})(); })();
``` ```

View File

@ -1,53 +0,0 @@
<html>
<head>
<script src="/dist/ffmpeg.dev.js"></script>
<style>
html,
body {
margin: 0;
width: 100%;
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
</head>
<body>
<h3>Upload a Video File</h3>
<video id="output-video" controls></video><br />
<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 transcode = async ({ target: { files } }) => {
const message = document.getElementById("message");
const { name } = files[0];
message.innerHTML = "Loading ffmpeg-core.js";
await worker.load();
message.innerHTML = "Start Concating";
await worker.write(name, files[0]);
const textFileName = "list.txt";
await worker.writeText(textFileName, `file ${name}\nfile ${name}`);
await worker.concatDemux(textFileName, "output.mp4");
message.innerHTML = "Complete Concating";
const { data } = await worker.read("output.mp4");
const video = document.getElementById("output-video");
video.src = URL.createObjectURL(
new Blob([data.buffer], { type: "video/mp4" })
);
};
const elm = document.getElementById("uploader");
elm.addEventListener("change", transcode);
</script>
</body>
</html>

View File

@ -122,9 +122,11 @@ module.exports = (_options = {}) => {
) )
); );
const concatDemux = (texFilePath, outputPath, opts = '', del = false, jobId) => { const concatDemuxer = async (inputPaths, outputPath, opts = '', del = true, jobId) => {
run(`${opts} -f concat -safe 0 -i /data/${texFilePath} -c copy ${outputPath}`, const text = inputPaths.reduce((acc, input) => `${acc}\nfile ${input}`, '');
{ del }, await writeText('concat_list.txt', text);
return run(`${opts} -f concat -safe 0 -i /data/concat_list.txt -c copy ${outputPath}`,
{ del, outputPath, inputPaths: [...inputPaths, 'concat_list.txt'] },
jobId); jobId);
}; };
@ -181,7 +183,7 @@ module.exports = (_options = {}) => {
run, run,
transcode, transcode,
trim, trim,
concatDemux, concatDemuxer,
ls, ls,
terminate, terminate,
}; };

View File

@ -66,7 +66,9 @@ const ls = ({
const run = async ({ const run = async ({
payload: { payload: {
args: _args, args: _args,
options: { inputPath, outputPath, del }, options: {
inputPath, inputPaths, outputPath, del,
},
}, },
}, res) => { }, res) => {
const args = [...defaultArgs, ..._args.trim().split(' ')]; const args = [...defaultArgs, ..._args.trim().split(' ')];
@ -75,6 +77,9 @@ const run = async ({
Module.FS.unlink(outputPath); Module.FS.unlink(outputPath);
if (del && typeof inputPath === 'string') { if (del && typeof inputPath === 'string') {
await adapter.fs.deleteFile(inputPath); await adapter.fs.deleteFile(inputPath);
} else if (del && Array.isArray(inputPaths)) {
inputPaths.reduce((promise, input) => promise.then(() => adapter.fs.deleteFile(input)),
Promise.resolve());
} }
res.resolve({ message: `Complete ${args.join(' ')}` }); res.resolve({ message: `Complete ${args.join(' ')}` });
}; };