Revise API and add worker.run

This commit is contained in:
jeromewu 2019-11-06 11:57:41 +00:00
parent db0c02a90a
commit c7234f23c0
8 changed files with 177 additions and 37 deletions

View File

@ -40,7 +40,9 @@ const worker = createWorker();
(async () => {
await worker.load();
const { data } = await worker.transcode('./test.avi', 'mp4');
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);
})();
```

47
examples/browser/run.html Normal file
View File

@ -0,0 +1,47 @@
<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 to transcode to mp4 (x264) and play!</h3>
<video id="output-video" controls></video><br/>
<input type="file" id="uploader">
<p id="message" />
<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 transcoding';
await worker.write(name, files[0]);
await worker.run(`-i ${name} output.mp4`);
message.innerHTML = 'Complete transcoding';
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

@ -28,11 +28,14 @@
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 transcoding';
const { data } = await worker.transcode(files[0], 'mp4');
await worker.write(name, files[0]);
await worker.transcode(name, 'output.mp4');
message.innerHTML = 'Complete transcoding';
const { data } = await worker.read('output.mp4');
const video = document.getElementById('output-video');
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));

17
examples/node/run.js Executable file
View File

@ -0,0 +1,17 @@
const fs = require('fs');
const { createWorker } = require('../../src');
const worker = createWorker({
logger: ({ message }) => console.log(message),
});
(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));
process.exit(0);
})();

View File

@ -1,9 +1,6 @@
const fs = require('fs');
const { createWorker } = require('../../src');
const { argv } = process;
const [,, inputPath, outputPath] = argv;
const worker = createWorker({
logger: ({ message }) => console.log(message),
});
@ -11,8 +8,10 @@ const worker = createWorker({
(async () => {
await worker.load();
console.log('Start transcoding');
const { data } = await worker.transcode(inputPath, outputPath.split('.').pop());
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');
fs.writeFileSync(outputPath, Buffer.from(data));
fs.writeFileSync('flame.mp4', Buffer.from(data));
process.exit(0);
})();

43
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "@ffmpeg/ffmpeg",
"version": "0.2.22",
"version": "0.2.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -3056,7 +3056,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -3077,12 +3078,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3097,17 +3100,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -3224,7 +3230,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -3236,6 +3243,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -3250,6 +3258,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3257,12 +3266,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -3281,6 +3292,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -3361,7 +3373,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -3373,6 +3386,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -3458,7 +3472,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -3494,6 +3509,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -3513,6 +3529,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -3556,12 +3573,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},

View File

@ -56,18 +56,41 @@ module.exports = (_options = {}) => {
}))
);
const transcode = async (media, outputExt, opts, jobId) => (
const write = async (path, data, jobId) => (
startJob(createJob({
id: jobId,
action: 'write',
payload: {
path,
data: await loadMedia(data),
},
}))
);
const transcode = (inputPath, outputPath, opts, jobId) => (
startJob(createJob({
id: jobId,
action: 'transcode',
payload: {
media: await loadMedia(media),
outputExt,
inputPath,
outputPath,
options: opts,
},
}))
);
const read = (path, jobId) => (
startJob(createJob({
id: jobId, action: 'read', payload: { path },
}))
);
const run = (args, jobId) => (
startJob(createJob({
id: jobId, action: 'run', payload: { args },
}))
);
const terminate = async (jobId) => {
if (worker !== null) {
await startJob(createJob({
@ -86,8 +109,10 @@ module.exports = (_options = {}) => {
if (status === 'resolve') {
log(`[${workerId}]: Complete ${jobId}`);
let d = data;
if (action === 'transcode') {
if (action === 'read') {
d = Uint8Array.from({ ...data, length: Object.keys(data).length });
} else {
logger(d);
}
resolves[action]({ jobId, data: d });
} else if (status === 'reject') {
@ -104,7 +129,10 @@ module.exports = (_options = {}) => {
setResolve,
setReject,
load,
write,
transcode,
read,
run,
terminate,
};
};

View File

@ -38,30 +38,52 @@ const load = ({ workerId, payload: { options: { corePath } } }, res) => {
});
});
ffmpeg = Module.cwrap('ffmpeg', 'number', ['number', 'number']);
res.resolve(true);
res.resolve({ message: 'Loaded ffmpeg-core' });
});
} else {
res.resolve(true);
res.resolve({ message: 'Loaded ffmpeg-core' });
}
};
const write = ({
payload: {
path,
data,
},
}, res) => {
const d = Uint8Array.from({ ...data, length: Object.keys(data).length });
Module.FS.writeFile(path, d);
res.resolve({ message: `Write ${path} (${d.length} bytes)` });
};
const transcode = ({
payload: {
media,
outputExt,
inputPath,
outputPath,
options = '',
},
}, res) => {
const data = Uint8Array.from({ ...media, length: Object.keys(media).length });
const iPath = 'media';
const oPath = `media.${outputExt}`;
const args = [...defaultArgs, ...`${options} -i file:${iPath} ${oPath}`.trim().split(' ')];
Module.FS.writeFile(iPath, data);
const args = [...defaultArgs, ...`${options} -i ${inputPath} ${outputPath}`.trim().split(' ')];
ffmpeg(args.length, strList2ptr(args));
const out = Module.FS.readFile(oPath);
Module.FS.unlink(iPath);
Module.FS.unlink(oPath);
res.resolve(out);
res.resolve({ message: `Complete transcoding ${inputPath} to ${outputPath}` });
};
const read = ({
payload: {
path,
},
}, res) => {
res.resolve(Module.FS.readFile(path));
};
const run = ({
payload: {
args: _args,
},
}, res) => {
const args = [...defaultArgs, ..._args.trim().split(' ')];
ffmpeg(args.length, strList2ptr(args));
res.resolve({ message: `Complete ./ffmpeg ${_args}` });
};
exports.dispatchHandlers = (packet, send) => {
@ -80,7 +102,10 @@ exports.dispatchHandlers = (packet, send) => {
try {
({
load,
write,
transcode,
read,
run,
})[packet.action](packet, res);
} catch (err) {
/** Prepare exception to travel through postMessage */