diff --git a/docs/api.md b/docs/api.md index da2e1b5..64aa62c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4,10 +4,12 @@ API - [createWorker()](#create-worker) - [Worker.load](#worker-load) - [Worker.write](#worker-write) + - [Worker.writeText](#worker-writeText) - [Worker.read](#worker-read) - [Worker.mkdir](#worker-mkdir) - [Worker.remove](#worker-remove) - [Worker.transcode](#worker-transcode) + - [Worker.trim](#worker-trim) - [Worker.run](#worker-run) --- @@ -72,6 +74,25 @@ Worker.write() writes data to specific path in Emscripten file system, it is an })(); ``` + +### Worker.writeText(path, text, jobId): Promise + +Worker.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` check Worker.load() + +**Examples:** + +```javascript +(async () => { + await worker.write('sub.srt', '...'); +})(); +``` + ### Worker.read(path, jobId): Promise @@ -146,6 +167,28 @@ Worker.transcode() transcode a video file to another format. })(); ``` + +### Worker.trim(inputPath, outputPath, from, to, options, jobId): Promise + +Worker.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 +- `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` check Worker.load() + +**Examples:** + +```javascript +(async () => { + await worker.trim('flame.avi', 'output.mp4', 1, 2); +})(); +``` + ### Worker.run(args, jobId): Promise diff --git a/examples/browser/trim.html b/examples/browser/trim.html new file mode 100644 index 0000000..1e7ade0 --- /dev/null +++ b/examples/browser/trim.html @@ -0,0 +1,47 @@ + + + + + + +

Upload a mp4 (x264) video and trim its first 2 seconds and play!

+
+ +

+ + + diff --git a/examples/node/trim.js b/examples/node/trim.js new file mode 100755 index 0000000..a03a9e5 --- /dev/null +++ b/examples/node/trim.js @@ -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 trimming'); + await worker.write('flame.avi', '../../tests/assets/flame.avi'); + await worker.trim('flame.avi', 'flame_trim.avi', 1, 2); + const { data } = await worker.read('flame_trim.avi'); + console.log('Complete trimming'); + fs.writeFileSync('flame_trim.avi', Buffer.from(data)); + process.exit(0); +})(); diff --git a/src/createWorker.js b/src/createWorker.js index d91153e..1531f52 100644 --- a/src/createWorker.js +++ b/src/createWorker.js @@ -69,18 +69,31 @@ module.exports = (_options = {}) => { })) ); - const transcode = (inputPath, outputPath, opts, jobId) => ( + const writeText = async (path, text, jobId) => ( startJob(createJob({ id: jobId, - action: 'transcode', + action: 'writeText', payload: { - inputPath, - outputPath, - options: opts, + path, + text, }, })) ); + const run = (args, jobId) => ( + startJob(createJob({ + id: jobId, action: 'run', payload: { args }, + })) + ); + + const transcode = (inputPath, outputPath, opts = '', jobId) => ( + run(`${opts} -i ${inputPath} ${outputPath}`, jobId) + ); + + const trim = (inputPath, outputPath, from, to, opts = '', jobId) => ( + run(`${opts} -ss ${from} -i ${inputPath} -t ${to} -c copy ${outputPath}`, jobId) + ); + const read = (path, jobId) => ( startJob(createJob({ id: jobId, action: 'read', payload: { path }, @@ -99,12 +112,6 @@ module.exports = (_options = {}) => { })) ); - const run = (args, jobId) => ( - startJob(createJob({ - id: jobId, action: 'run', payload: { args }, - })) - ); - const terminate = async (jobId) => { if (worker !== null) { await startJob(createJob({ @@ -145,7 +152,9 @@ module.exports = (_options = {}) => { setReject, load, write, + writeText, transcode, + trim, read, remove, mkdir, diff --git a/src/worker-script/index.js b/src/worker-script/index.js index 3eb95b5..a63eb57 100644 --- a/src/worker-script/index.js +++ b/src/worker-script/index.js @@ -26,11 +26,6 @@ const strList2ptr = (strList) => { return listPtr; }; -const doRun = (_args) => { - const args = [...defaultArgs, ..._args.trim().split(' ')]; - ffmpeg(args.length, strList2ptr(args)); -}; - const load = ({ workerId, payload: { options: { corePath } } }, res) => { if (Module == null) { const Core = adapter.getCore(corePath); @@ -61,15 +56,14 @@ const write = ({ res.resolve({ message: `Write ${path} (${d.length} bytes)` }); }; -const transcode = ({ +const writeText = ({ payload: { - inputPath, - outputPath, - options = '', + path, + text, }, }, res) => { - doRun(`${options} -i ${inputPath} ${outputPath}`); - res.resolve({ message: `Complete transcoding ${inputPath} to ${outputPath}` }); + Module.FS.writeFile(path, text); + res.resolve({ message: `Write ${path} (${text.length} bytes)` }); }; const read = ({ @@ -100,11 +94,12 @@ const mkdir = ({ const run = ({ payload: { - args, + args: _args, }, }, res) => { - doRun(args); - res.resolve({ message: `Complete ./ffmpeg ${args}` }); + const args = [...defaultArgs, ..._args.trim().split(' ')]; + ffmpeg(args.length, strList2ptr(args)); + res.resolve({ message: `Complete ${args.join(' ')}` }); }; exports.dispatchHandlers = (packet, send) => { @@ -124,7 +119,7 @@ exports.dispatchHandlers = (packet, send) => { ({ load, write, - transcode, + writeText, read, remove, mkdir,