Add Worker.trim
This commit is contained in:
parent
7a380f529b
commit
e06c9bd19a
43
docs/api.md
43
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
|
||||
})();
|
||||
```
|
||||
|
||||
<a name="worker-writeText"></a>
|
||||
### 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', '...');
|
||||
})();
|
||||
```
|
||||
|
||||
<a name="worker-read"></a>
|
||||
### Worker.read(path, jobId): Promise
|
||||
|
||||
@ -146,6 +167,28 @@ Worker.transcode() transcode a video file to another format.
|
||||
})();
|
||||
```
|
||||
|
||||
<a name="worker-trim"></a>
|
||||
### 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);
|
||||
})();
|
||||
```
|
||||
|
||||
<a name="worker-run"></a>
|
||||
### Worker.run(args, jobId): Promise
|
||||
|
||||
|
47
examples/browser/trim.html
Normal file
47
examples/browser/trim.html
Normal 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 mp4 (x264) video and trim its first 2 seconds and play!</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 trimming';
|
||||
await worker.write(name, files[0]);
|
||||
await worker.trim(name, 'output.mp4', 0, 2);
|
||||
message.innerHTML = 'Complete trimming';
|
||||
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>
|
17
examples/node/trim.js
Executable file
17
examples/node/trim.js
Executable 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 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);
|
||||
})();
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user