@uploadista/flow-videos-av-node 0.0.13-beta.1

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.
@@ -0,0 +1,16 @@
1
+
2
+ 
3
+ > @uploadista/flow-videos-av-node@0.0.12 build /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/flow/videos/av-node
4
+ > tsdown
5
+
6
+ ℹ tsdown v0.16.0 powered by rolldown v1.0.0-beta.46
7
+ ℹ entry: src/index.ts
8
+ ℹ tsconfig: tsconfig.json
9
+ ℹ Build start
10
+ ℹ Cleaning 4 files
11
+ ℹ dist/index.mjs 17.17 kB │ gzip: 3.52 kB
12
+ ℹ dist/index.mjs.map 33.87 kB │ gzip: 6.59 kB
13
+ ℹ dist/index.d.mts.map  0.88 kB │ gzip: 0.46 kB
14
+ ℹ dist/index.d.mts  3.37 kB │ gzip: 1.04 kB
15
+ ℹ 4 files, total: 55.28 kB
16
+ ✔ Build complete in 10244ms
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 uploadista
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # @uploadista/flow-videos-av-node
2
+
3
+ Modern FFmpeg-based video processing plugin for Uploadista Flow using node-av. Provides video transcoding, resizing, trimming, thumbnail generation, and metadata extraction with native FFmpeg bindings.
4
+
5
+ ## Features
6
+
7
+ - **No System Dependencies**: node-av includes prebuilt FFmpeg binaries - no system installation required
8
+ - **TypeScript Native**: Full type safety with modern TypeScript support
9
+ - **Modern API**: Uses native async/await and AsyncIterators
10
+ - **Memory Efficient**: Automatic resource management with `using` declarations
11
+ - **Cross-Platform**: Works on Windows, macOS, and Linux out of the box
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @uploadista/flow-videos-av-node
17
+ ```
18
+
19
+ No additional dependencies or system packages required - FFmpeg binaries are included with node-av.
20
+
21
+ ## Usage
22
+
23
+ ### Provide the Plugin Layer
24
+
25
+ ```typescript
26
+ import { AVNodeVideoPluginLive } from "@uploadista/flow-videos-av-node";
27
+ import { Effect } from "effect";
28
+
29
+ // Provide the node-av plugin to your flow execution
30
+ const result = await Effect.runPromise(
31
+ flowProgram.pipe(Effect.provide(AVNodeVideoPluginLive))
32
+ );
33
+ ```
34
+
35
+ ### With Availability Check
36
+
37
+ ```typescript
38
+ import { AVNodeVideoPluginWithCheck } from "@uploadista/flow-videos-av-node";
39
+
40
+ // Checks node-av availability on initialization
41
+ const result = await Effect.runPromise(
42
+ flowProgram.pipe(Effect.provide(AVNodeVideoPluginWithCheck))
43
+ );
44
+ // Logs: "✓ node-av 3.x detected" or warning if not found
45
+ ```
46
+
47
+ ## Supported Formats
48
+
49
+ ### Input Formats
50
+
51
+ - MP4 (MPEG-4)
52
+ - WebM (VP8/VP9)
53
+ - MOV (QuickTime)
54
+ - AVI (Audio Video Interleave)
55
+ - MKV (Matroska)
56
+ - FLV (Flash Video)
57
+
58
+ ### Output Formats
59
+
60
+ - MP4 (H.264/AAC) - Most compatible
61
+ - WebM (VP9/Opus) - Modern web standard
62
+ - MOV (H.264/AAC) - Apple ecosystem
63
+ - AVI (various codecs)
64
+
65
+ ### Video Codecs
66
+
67
+ - **H.264** (`h264`) - Universal compatibility
68
+ - **H.265/HEVC** (`hevc`) - Better compression
69
+ - **VP9** (`vp9`) - Open-source, good for web
70
+ - **AV1** (`av1`) - Next-gen, best compression
71
+
72
+ ### Audio Codecs
73
+
74
+ - **AAC** - Standard for MP4
75
+ - **Opus** - Modern, efficient
76
+ - **MP3** - Legacy compatibility
77
+ - **Vorbis** - WebM standard
78
+
79
+ ## Error Handling
80
+
81
+ The plugin uses typed UploadistaError codes:
82
+
83
+ - `VIDEO_PROCESSING_FAILED` - Generic processing error
84
+ - `INVALID_VIDEO_FORMAT` - Unsupported format
85
+ - `CODEC_NOT_SUPPORTED` - Codec unavailable
86
+ - `VIDEO_METADATA_EXTRACTION_FAILED` - Cannot read metadata
87
+
88
+ ```typescript
89
+ import { Effect } from "effect";
90
+ import { UploadistaError } from "@uploadista/core/errors";
91
+
92
+ const program = Effect.gen(function* () {
93
+ const videoPlugin = yield* VideoPlugin;
94
+ const result = yield* videoPlugin.transcode(videoBytes, {
95
+ format: "webm",
96
+ codec: "vp9",
97
+ });
98
+ return result;
99
+ }).pipe(
100
+ Effect.catchTag("UploadistaError", (error) => {
101
+ if (error.code === "VIDEO_PROCESSING_FAILED") {
102
+ console.error("Video processing failed:", error.message);
103
+ }
104
+ return Effect.fail(error);
105
+ })
106
+ );
107
+ ```
108
+
109
+ ## Performance Considerations
110
+
111
+ Video processing is computationally intensive. Approximate processing times (on modern CPU):
112
+
113
+ | Operation | 1 min video | 5 min video |
114
+ | ------------------------ | ----------- | ----------- |
115
+ | Transcode H.264 → WebM | ~30s | ~2.5m |
116
+ | Resize 1080p → 720p | ~15s | ~1.5m |
117
+ | Thumbnail extraction | ~2s | ~2s |
118
+ | Metadata extraction | <1s | <1s |
119
+ | Trim (with re-encode) | ~10s | ~50s |
120
+
121
+ Times vary based on video complexity, codec settings, and hardware.
122
+
123
+ ## Advantages over fluent-ffmpeg
124
+
125
+ - **Modern**: node-av is actively maintained with TypeScript support
126
+ - **No System Dependencies**: Includes prebuilt FFmpeg binaries
127
+ - **Type Safe**: Full TypeScript definitions and modern API
128
+ - **Memory Efficient**: Better resource management with automatic cleanup
129
+ - **Performance**: Direct FFmpeg bindings without wrapper overhead
130
+
131
+ ## Current Limitations
132
+
133
+ This is an initial implementation focusing on core functionality:
134
+
135
+ - **Resize Quality**: Currently uses encoder-based resizing. For production use, consider adding FilterAPI support for better quality scaling
136
+ - **Frame Extraction**: Extracts frames as MJPEG or PNG. Additional format support can be added
137
+ - **Hardware Acceleration**: Not yet implemented, but node-av supports it via HardwareContext
138
+
139
+ ## Roadmap
140
+
141
+ Future improvements planned:
142
+
143
+ 1. **FilterAPI Integration**: Add support for high-quality video filters (scale, crop, overlay, etc.)
144
+ 2. **Hardware Acceleration**: GPU-accelerated encoding/decoding support
145
+ 3. **Additional Formats**: Support for more image formats in frame extraction
146
+ 4. **Stream Processing**: Direct stream input/output without temporary files
147
+ 5. **Progress Callbacks**: Real-time progress reporting for long operations
148
+
149
+ ## Troubleshooting
150
+
151
+ ### Import Error
152
+
153
+ **Error**: Cannot find module 'node-av'
154
+
155
+ **Solution**: Ensure node-av is installed:
156
+
157
+ ```bash
158
+ npm install node-av
159
+ ```
160
+
161
+ ### TypeScript Errors
162
+
163
+ **Error**: TypeScript compilation errors
164
+
165
+ **Solution**: node-av requires modern TypeScript features. Ensure you're using TypeScript 5.2+:
166
+
167
+ ```bash
168
+ npm install -D typescript@latest
169
+ ```
170
+
171
+ ## Comparison with @uploadista/flow-videos-ffmpeg
172
+
173
+ | Feature | av-node (this package) | ffmpeg (fluent-ffmpeg) |
174
+ |---------|----------------------|------------------------|
175
+ | System Dependencies | ❌ None (bundled) | ✅ Requires FFmpeg install |
176
+ | Maintenance | ✅ Active | ⚠️ Deprecated |
177
+ | TypeScript Support | ✅ Native | ⚠️ Via @types |
178
+ | API Style | ✅ Modern async/await | ⚠️ Callback-based |
179
+ | Memory Management | ✅ Automatic | ⚠️ Manual |
180
+ | Performance | ✅ Direct bindings | ⚠️ CLI wrapper |
181
+
182
+ **Recommendation**: Use this package (@uploadista/flow-videos-av-node) for new projects. The fluent-ffmpeg package is deprecated and unmaintained.
183
+
184
+ ## License
185
+
186
+ MIT
@@ -0,0 +1,99 @@
1
+ import { FFEncoderCodec } from "node-av/constants";
2
+ import { Layer } from "effect";
3
+ import { TranscodeParams, VideoPlugin, VideoPluginShape } from "@uploadista/core/flow";
4
+
5
+ //#region src/utils/av-check.d.ts
6
+ /**
7
+ * Result of node-av availability check
8
+ */
9
+ type AVCheckResult = {
10
+ available: boolean;
11
+ version?: string;
12
+ error?: string;
13
+ };
14
+ /**
15
+ * Checks if node-av is available and can access FFmpeg binaries
16
+ * @returns Promise with availability status and version info
17
+ */
18
+ declare function checkAVAvailable(): Promise<AVCheckResult>;
19
+ //#endregion
20
+ //#region src/utils/format-mappings.d.ts
21
+ /**
22
+ * Maps video format to MIME type
23
+ */
24
+ declare const formatToMimeType: Record<TranscodeParams["format"], string>;
25
+ /**
26
+ * Maps video format to file extension
27
+ */
28
+ declare const formatToExtension: Record<TranscodeParams["format"], string>;
29
+ /**
30
+ * Maps codec parameter to node-av codec constant
31
+ */
32
+ declare const codecToAVName: Record<NonNullable<TranscodeParams["codec"]>, FFEncoderCodec>;
33
+ /**
34
+ * Maps audio codec parameter to node-av audio codec constant
35
+ */
36
+ declare const audioCodecToAVName: Record<NonNullable<TranscodeParams["audioCodec"]>, FFEncoderCodec>;
37
+ /**
38
+ * Maps image format to encoder constant
39
+ */
40
+ declare const imageFormatToEncoder: Record<string, FFEncoderCodec>;
41
+ //#endregion
42
+ //#region src/video-plugin.d.ts
43
+ /**
44
+ * Creates a node-av based video processing plugin
45
+ */
46
+ declare function createAVNodeVideoPlugin(): VideoPluginShape;
47
+ //#endregion
48
+ //#region src/video-plugin-layer.d.ts
49
+ /**
50
+ * Effect Layer for the node-av video plugin
51
+ *
52
+ * This layer provides video processing capabilities using node-av (FFmpeg bindings).
53
+ * Note: node-av includes prebuilt FFmpeg binaries, so no system installation is required.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * import { AVNodeVideoPlugin } from "@uploadista/flow-videos-av-node";
58
+ * import { Effect } from "effect";
59
+ *
60
+ * const program = Effect.gen(function* () {
61
+ * const videoPlugin = yield* VideoPlugin;
62
+ * const metadata = yield* videoPlugin.describe(videoBytes);
63
+ * return metadata;
64
+ * });
65
+ *
66
+ * // Run with node-av plugin layer
67
+ * const result = await Effect.runPromise(
68
+ * program.pipe(Effect.provide(AVNodeVideoPluginLive))
69
+ * );
70
+ * ```
71
+ */
72
+ declare const AVNodeVideoPlugin: Layer.Layer<VideoPlugin, never, never>;
73
+ /**
74
+ * Effect Layer for the node-av video plugin with availability check
75
+ *
76
+ * This layer checks if node-av is properly installed and logs status information.
77
+ * The plugin will still be created, but operations will fail if node-av is not available.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * import { AVNodeVideoPluginWithCheck } from "@uploadista/flow-videos-av-node";
82
+ * import { Effect } from "effect";
83
+ *
84
+ * const program = Effect.gen(function* () {
85
+ * const videoPlugin = yield* VideoPlugin;
86
+ * const metadata = yield* videoPlugin.describe(videoBytes);
87
+ * return metadata;
88
+ * });
89
+ *
90
+ * // Run with node-av plugin layer (with check)
91
+ * const result = await Effect.runPromise(
92
+ * program.pipe(Effect.provide(AVNodeVideoPluginWithCheck))
93
+ * );
94
+ * ```
95
+ */
96
+ declare const AVNodeVideoPluginWithCheck: Layer.Layer<VideoPlugin, never, never>;
97
+ //#endregion
98
+ export { AVCheckResult, AVNodeVideoPlugin, AVNodeVideoPluginWithCheck, audioCodecToAVName, checkAVAvailable, codecToAVName, createAVNodeVideoPlugin, formatToExtension, formatToMimeType, imageFormatToEncoder };
99
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils/av-check.ts","../src/utils/format-mappings.ts","../src/video-plugin.ts","../src/video-plugin-layer.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAGY,aAAA;;EAAA,OAAA,CAAA,EAAA,MAAa;EAUH,KAAA,CAAA,EAAA,MAAA;;;;ACKtB;AAUA;AAUa,iBDzBS,gBAAA,CAAA,CCiCrB,EDjCyC,OCiCzC,CDjCiD,aCiCjD,CAAA;;;;;;AD3CW,cCeC,gBDfY,ECeM,MDfN,CCea,eDfb,CAAA,QAAA,CAAA,EAAA,MAAA,CAAA;AAUzB;;;cCea,mBAAmB,OAAO;AAVvC;AAUA;AAUA;AACc,cADD,aACC,EADc,MACd,CAAZ,WAAY,CAAA,eAAA,CAAA,OAAA,CAAA,CAAA,EACZ,cADY,CAAA;;;;AADoB,cAarB,kBAbqB,EAaD,MAbC,CAchC,WAdgC,CAcpB,eAdoB,CAAA,YAAA,CAAA,CAAA,EAehC,cAfgC,CAAA;AAalC;;;AAEE,cAWW,oBAXX,EAWiC,MAXjC,CAAA,MAAA,EAWgD,cAXhD,CAAA;;;;;;iBC9Bc,uBAAA,CAAA,GAA2B;;;;;;AFpB3C;AAUA;;;;ACKA;AAUA;AAUA;;;;;;AAaA;;;;;;AAaA;cEpCa,mBAAiB,KAAA,CAAA,MAAA;;;ADL9B;;;;ACKA;AA4BA;;;;;;;;;;;;;;;;cAAa,4BAA0B,KAAA,CAAA,MAAA"}