Skip to content

Commit 6a8d4bb

Browse files
committed
Add Worker.trim
1 parent 0a66de7 commit 6a8d4bb

File tree

5 files changed

+137
-26
lines changed

5 files changed

+137
-26
lines changed

docs/api.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ API
44
- [createWorker()](#create-worker)
55
- [Worker.load](#worker-load)
66
- [Worker.write](#worker-write)
7+
- [Worker.writeText](#worker-writeText)
78
- [Worker.read](#worker-read)
89
- [Worker.mkdir](#worker-mkdir)
910
- [Worker.remove](#worker-remove)
1011
- [Worker.transcode](#worker-transcode)
12+
- [Worker.trim](#worker-trim)
1113
- [Worker.run](#worker-run)
1214

1315
---
@@ -72,6 +74,25 @@ Worker.write() writes data to specific path in Emscripten file system, it is an
7274
})();
7375
```
7476

77+
<a name="worker-writeText"></a>
78+
### Worker.writeText(path, text, jobId): Promise
79+
80+
Worker.write() writes text data to specific path in Emscripten file system.
81+
82+
**Arguments:**
83+
84+
- `path` path to write data to file system
85+
- `text` string to write to file
86+
- `jobId` check Worker.load()
87+
88+
**Examples:**
89+
90+
```javascript
91+
(async () => {
92+
await worker.write('sub.srt', '...');
93+
})();
94+
```
95+
7596
<a name="worker-read"></a>
7697
### Worker.read(path, jobId): Promise
7798

@@ -146,6 +167,28 @@ Worker.transcode() transcode a video file to another format.
146167
})();
147168
```
148169

170+
<a name="worker-trim"></a>
171+
### Worker.trim(inputPath, outputPath, from, to, options, jobId): Promise
172+
173+
Worker.trim() trims video to specific interval.
174+
175+
**Arguments:**
176+
177+
- `inputPath` input file path, the input file should be written through Worker.write()
178+
- `outputPath` output file path, can be read with Worker.read() later
179+
- `from` start time, can be in time stamp (00:00:12.000) or seconds (12)
180+
- `to` end time, rule same as above
181+
- `options` a string to add extra arguments to ffmpeg
182+
- `jobId` check Worker.load()
183+
184+
**Examples:**
185+
186+
```javascript
187+
(async () => {
188+
await worker.trim('flame.avi', 'output.mp4', 1, 2);
189+
})();
190+
```
191+
149192
<a name="worker-run"></a>
150193
### Worker.run(args, jobId): Promise
151194

examples/browser/trim.html

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<html>
2+
<head>
3+
<script src="/dist/ffmpeg.dev.js"></script>
4+
<style>
5+
html, body {
6+
margin: 0;
7+
width: 100%;
8+
height: 100%
9+
}
10+
body {
11+
display: flex;
12+
flex-direction: column;
13+
align-items: center;
14+
}
15+
</style>
16+
</head>
17+
<body>
18+
<h3>Upload a mp4 (x264) video and trim its first 2 seconds and play!</h3>
19+
<video id="output-video" controls></video><br/>
20+
<input type="file" id="uploader">
21+
<p id="message"></p>
22+
<script>
23+
const { createWorker } = FFmpeg;
24+
const worker = createWorker({
25+
corePath: '../../node_modules/@ffmpeg/core/ffmpeg-core.js',
26+
logger: ({ message }) => console.log(message),
27+
});
28+
29+
const transcode = async ({ target: { files } }) => {
30+
const message = document.getElementById('message');
31+
const { name } = files[0];
32+
message.innerHTML = 'Loading ffmpeg-core.js';
33+
await worker.load();
34+
message.innerHTML = 'Start trimming';
35+
await worker.write(name, files[0]);
36+
await worker.trim(name, 'output.mp4', 0, 2);
37+
message.innerHTML = 'Complete trimming';
38+
const { data } = await worker.read('output.mp4');
39+
40+
const video = document.getElementById('output-video');
41+
video.src = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
42+
}
43+
const elm = document.getElementById('uploader');
44+
elm.addEventListener('change', transcode);
45+
</script>
46+
</body>
47+
</html>

examples/node/trim.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const fs = require('fs');
2+
const { createWorker } = require('../../src');
3+
4+
const worker = createWorker({
5+
logger: ({ message }) => console.log(message),
6+
});
7+
8+
(async () => {
9+
await worker.load();
10+
console.log('Start trimming');
11+
await worker.write('flame.avi', '../../tests/assets/flame.avi');
12+
await worker.trim('flame.avi', 'flame_trim.avi', 1, 2);
13+
const { data } = await worker.read('flame_trim.avi');
14+
console.log('Complete trimming');
15+
fs.writeFileSync('flame_trim.avi', Buffer.from(data));
16+
process.exit(0);
17+
})();

src/createWorker.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,31 @@ module.exports = (_options = {}) => {
6969
}))
7070
);
7171

72-
const transcode = (inputPath, outputPath, opts, jobId) => (
72+
const writeText = async (path, text, jobId) => (
7373
startJob(createJob({
7474
id: jobId,
75-
action: 'transcode',
75+
action: 'writeText',
7676
payload: {
77-
inputPath,
78-
outputPath,
79-
options: opts,
77+
path,
78+
text,
8079
},
8180
}))
8281
);
8382

83+
const run = (args, jobId) => (
84+
startJob(createJob({
85+
id: jobId, action: 'run', payload: { args },
86+
}))
87+
);
88+
89+
const transcode = (inputPath, outputPath, opts = '', jobId) => (
90+
run(`${opts} -i ${inputPath} ${outputPath}`, jobId)
91+
);
92+
93+
const trim = (inputPath, outputPath, from, to, opts = '', jobId) => (
94+
run(`${opts} -ss ${from} -i ${inputPath} -t ${to} -c copy ${outputPath}`, jobId)
95+
);
96+
8497
const read = (path, jobId) => (
8598
startJob(createJob({
8699
id: jobId, action: 'read', payload: { path },
@@ -99,12 +112,6 @@ module.exports = (_options = {}) => {
99112
}))
100113
);
101114

102-
const run = (args, jobId) => (
103-
startJob(createJob({
104-
id: jobId, action: 'run', payload: { args },
105-
}))
106-
);
107-
108115
const terminate = async (jobId) => {
109116
if (worker !== null) {
110117
await startJob(createJob({
@@ -145,7 +152,9 @@ module.exports = (_options = {}) => {
145152
setReject,
146153
load,
147154
write,
155+
writeText,
148156
transcode,
157+
trim,
149158
read,
150159
remove,
151160
mkdir,

src/worker-script/index.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ const strList2ptr = (strList) => {
2626
return listPtr;
2727
};
2828

29-
const doRun = (_args) => {
30-
const args = [...defaultArgs, ..._args.trim().split(' ')];
31-
ffmpeg(args.length, strList2ptr(args));
32-
};
33-
3429
const load = ({ workerId, payload: { options: { corePath } } }, res) => {
3530
if (Module == null) {
3631
const Core = adapter.getCore(corePath);
@@ -61,15 +56,14 @@ const write = ({
6156
res.resolve({ message: `Write ${path} (${d.length} bytes)` });
6257
};
6358

64-
const transcode = ({
59+
const writeText = ({
6560
payload: {
66-
inputPath,
67-
outputPath,
68-
options = '',
61+
path,
62+
text,
6963
},
7064
}, res) => {
71-
doRun(`${options} -i ${inputPath} ${outputPath}`);
72-
res.resolve({ message: `Complete transcoding ${inputPath} to ${outputPath}` });
65+
Module.FS.writeFile(path, text);
66+
res.resolve({ message: `Write ${path} (${text.length} bytes)` });
7367
};
7468

7569
const read = ({
@@ -100,11 +94,12 @@ const mkdir = ({
10094

10195
const run = ({
10296
payload: {
103-
args,
97+
args: _args,
10498
},
10599
}, res) => {
106-
doRun(args);
107-
res.resolve({ message: `Complete ./ffmpeg ${args}` });
100+
const args = [...defaultArgs, ..._args.trim().split(' ')];
101+
ffmpeg(args.length, strList2ptr(args));
102+
res.resolve({ message: `Complete ${args.join(' ')}` });
108103
};
109104

110105
exports.dispatchHandlers = (packet, send) => {
@@ -124,7 +119,7 @@ exports.dispatchHandlers = (packet, send) => {
124119
({
125120
load,
126121
write,
127-
transcode,
122+
writeText,
128123
read,
129124
remove,
130125
mkdir,

0 commit comments

Comments
 (0)