@open-motion/encoder 0.0.1-alpha.0 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +34 -9
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @open-motion/encoder
|
|
2
|
+
|
|
3
|
+
The FFmpeg-powered encoding engine for **OpenMotion**.
|
|
4
|
+
|
|
5
|
+
This package handles:
|
|
6
|
+
- Merging image sequences into high-quality MP4 files.
|
|
7
|
+
- Managing frame rates and output quality (CRF).
|
|
8
|
+
- Future support for audio track mixing and multi-track encoding.
|
|
9
|
+
|
|
10
|
+
## 🛠 Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @open-motion/encoder
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 📖 Requirements
|
|
17
|
+
|
|
18
|
+
You must have `ffmpeg` installed on your system.
|
|
19
|
+
|
|
20
|
+
## 📖 Usage
|
|
21
|
+
|
|
22
|
+
Typically used internally by the `@open-motion/cli`.
|
|
23
|
+
|
|
24
|
+
Learn more at the [main OpenMotion repository](https://github.com/jsongo/open-motion).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
export interface AudioAsset {
|
|
2
|
+
src: string;
|
|
3
|
+
startFrame: number;
|
|
4
|
+
startFrom?: number;
|
|
5
|
+
volume?: number;
|
|
6
|
+
}
|
|
1
7
|
export interface EncodeOptions {
|
|
2
8
|
framesDir: string;
|
|
3
9
|
fps: number;
|
|
4
10
|
outputFile: string;
|
|
5
|
-
|
|
11
|
+
audioAssets?: AudioAsset[];
|
|
12
|
+
onProgress?: (percent: number) => void;
|
|
6
13
|
}
|
|
7
|
-
export declare const encodeVideo: ({ framesDir, fps, outputFile,
|
|
14
|
+
export declare const encodeVideo: ({ framesDir, fps, outputFile, audioAssets, onProgress }: EncodeOptions) => Promise<unknown>;
|
package/dist/index.js
CHANGED
|
@@ -6,24 +6,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.encodeVideo = void 0;
|
|
7
7
|
const fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const encodeVideo = ({ framesDir, fps, outputFile, audioAssets = [], onProgress }) => {
|
|
11
|
+
// Verify frames exist
|
|
12
|
+
const files = fs_1.default.readdirSync(framesDir).filter(f => f.startsWith('frame-') && f.endsWith('.png'));
|
|
13
|
+
if (files.length === 0) {
|
|
14
|
+
throw new Error(`No frames found in ${framesDir}`);
|
|
15
|
+
}
|
|
16
|
+
// console.log(`Found ${files.length} frames for encoding.`);
|
|
10
17
|
return new Promise((resolve, reject) => {
|
|
11
18
|
const command = (0, fluent_ffmpeg_1.default)()
|
|
12
19
|
.input(path_1.default.join(framesDir, 'frame-%05d.png'))
|
|
13
|
-
.inputFPS(fps)
|
|
14
|
-
|
|
20
|
+
.inputFPS(fps);
|
|
21
|
+
// DEBUG: Force a local audio input regardless of what the CLI says
|
|
22
|
+
const debugAudioPath = '/Users/jsongo/code/creation/open-motion/examples/demo/public/test-audio.mp3';
|
|
23
|
+
console.log(`DEBUG: FORCING FFmpeg to use audio: ${debugAudioPath}`);
|
|
24
|
+
command.input(debugAudioPath);
|
|
25
|
+
const videoOptions = [
|
|
15
26
|
'-c:v libx264',
|
|
16
27
|
'-pix_fmt yuv420p',
|
|
17
28
|
'-crf 18'
|
|
29
|
+
];
|
|
30
|
+
const filters = [
|
|
31
|
+
`[1:a]atrim=end=10,asetpts=PTS-STARTPTS,volume=1[a]`
|
|
32
|
+
];
|
|
33
|
+
command.complexFilter(filters);
|
|
34
|
+
command.outputOptions([
|
|
35
|
+
...videoOptions,
|
|
36
|
+
'-map 0:v',
|
|
37
|
+
'-map [a]',
|
|
38
|
+
'-c:a aac',
|
|
39
|
+
'-shortest'
|
|
18
40
|
]);
|
|
19
|
-
if (audioFile) {
|
|
20
|
-
command.input(audioFile);
|
|
21
|
-
}
|
|
22
41
|
command
|
|
23
|
-
.on('start', (cmd) =>
|
|
24
|
-
.
|
|
42
|
+
.on('start', (cmd) => {
|
|
43
|
+
console.log('DEBUG: FFmpeg COMMAND LINE:', cmd);
|
|
44
|
+
})
|
|
45
|
+
.on('progress', (progress) => {
|
|
46
|
+
if (progress.percent && onProgress) {
|
|
47
|
+
onProgress(progress.percent);
|
|
48
|
+
}
|
|
49
|
+
})
|
|
25
50
|
.on('end', () => {
|
|
26
|
-
console.log('Encoding finished.');
|
|
51
|
+
// console.log('Encoding finished.');
|
|
27
52
|
resolve(outputFile);
|
|
28
53
|
})
|
|
29
54
|
.on('error', (err) => {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-motion/encoder",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/jsongo/open-motion.git",
|
|
10
10
|
"directory": "packages/encoder"
|
|
11
11
|
},
|
|
12
12
|
"publishConfig": {
|