@honem/native-video-compressor 0.1.0

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,15 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = 'HonemNativeVideoCompressor'
3
+ s.version = '0.1.0'
4
+ s.summary = 'Capacitor plugin for video compression using native platform APIs'
5
+ s.license = 'MIT'
6
+ s.homepage = 'https://github.com/honem/native-video-compressor'
7
+ s.author = 'honem'
8
+ s.source = { :git => 'https://github.com/honem/native-video-compressor.git', :tag => s.version.to_s }
9
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
10
+ s.ios.deployment_target = '15.0'
11
+ s.dependency 'Capacitor'
12
+ s.swift_version = '5.1'
13
+ s.static_framework = true
14
+ end
15
+
package/README.md ADDED
@@ -0,0 +1,283 @@
1
+ # @honem/native-video-compressor
2
+
3
+ Capacitor plugin for video compression using native platform APIs (iOS AVFoundation, Android MediaCodec, Electron FFmpeg).
4
+
5
+ ## Features
6
+
7
+ - ✅ **Native Performance**: Uses platform-native APIs for optimal performance
8
+ - ✅ **Multiple Formats**: Supports MP4, MOV, M4V, 3GP, and WebM
9
+ - ✅ **Configurable Quality**: Low, Medium, High, and Custom quality presets
10
+ - ✅ **Progress Tracking**: Real-time compression progress callbacks
11
+ - ✅ **Cross-Platform**: iOS, Android, and Electron support
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @honem/native-video-compressor
17
+ npx cap sync
18
+ ```
19
+
20
+ ### Electron Setup
21
+
22
+ For Electron apps, you also need to install FFmpeg dependencies:
23
+
24
+ ```bash
25
+ npm install fluent-ffmpeg @ffmpeg-installer/ffmpeg
26
+ ```
27
+
28
+ Then register the plugin in your Electron main process (see [Electron Setup](#electron-setup) below).
29
+
30
+ ## Usage
31
+
32
+ ### Basic Usage
33
+
34
+ ```typescript
35
+ import { VideoCompressor } from '@honem/native-video-compressor';
36
+
37
+ const result = await VideoCompressor.compressVideo({
38
+ inputPath: '/path/to/input/video.mp4',
39
+ quality: 'medium',
40
+ // Format will be auto-detected from input file (MOV → MOV, MP4 → MP4)
41
+ // format: 'mp4', // Optional: specify format to override auto-detection
42
+ onProgress: (progress) => {
43
+ console.log(`Compression progress: ${progress}%`);
44
+ }
45
+ });
46
+
47
+ console.log(`Compressed video saved to: ${result.outputPath}`);
48
+ console.log(`Compression ratio: ${result.compressionRatio}x`);
49
+ ```
50
+
51
+ ### Quality Presets
52
+
53
+ #### Low Quality
54
+ ```typescript
55
+ await VideoCompressor.compressVideo({
56
+ inputPath: '/path/to/video.mp4',
57
+ quality: 'low', // 640x480, 500 kbps
58
+ });
59
+ ```
60
+
61
+ #### Medium Quality (Default)
62
+ ```typescript
63
+ await VideoCompressor.compressVideo({
64
+ inputPath: '/path/to/video.mp4',
65
+ quality: 'medium', // 1280x720, 2 Mbps
66
+ });
67
+ ```
68
+
69
+ #### High Quality
70
+ ```typescript
71
+ await VideoCompressor.compressVideo({
72
+ inputPath: '/path/to/video.mp4',
73
+ quality: 'high', // Original resolution, 8 Mbps
74
+ });
75
+ ```
76
+
77
+ #### Custom Quality
78
+ ```typescript
79
+ await VideoCompressor.compressVideo({
80
+ inputPath: '/path/to/video.mp4',
81
+ quality: 'custom',
82
+ bitrate: 4000000, // 4 Mbps
83
+ width: 1920,
84
+ height: 1080,
85
+ format: 'mp4',
86
+ });
87
+ ```
88
+
89
+ ### Progress Tracking
90
+
91
+ **Note**: Progress callbacks (`onProgress`) are currently not supported on iOS and Android due to Capacitor's architecture limitations. Progress tracking would require implementing Capacitor's event system with `notifyListeners()`. For now, progress callbacks only work on Electron.
92
+
93
+ ```typescript
94
+ await VideoCompressor.compressVideo({
95
+ inputPath: '/path/to/video.mp4',
96
+ quality: 'medium',
97
+ onProgress: (progress) => {
98
+ // Progress is a number from 0 to 100
99
+ // Currently only works on Electron
100
+ updateProgressBar(progress);
101
+ }
102
+ });
103
+ ```
104
+
105
+ ### Custom Output Path
106
+
107
+ ```typescript
108
+ await VideoCompressor.compressVideo({
109
+ inputPath: '/path/to/input/video.mp4',
110
+ outputPath: '/path/to/output/compressed.mp4',
111
+ quality: 'medium',
112
+ });
113
+ ```
114
+
115
+ If `outputPath` is not provided, the plugin will automatically generate a path by appending `_compressed` to the input filename.
116
+
117
+ ## API Reference
118
+
119
+ ### `compressVideo(options: CompressionOptions): Promise<CompressionResult>`
120
+
121
+ Compresses a video file.
122
+
123
+ #### Parameters
124
+
125
+ **`options`** (CompressionOptions)
126
+
127
+ - `inputPath` (string, required): Path to the input video file
128
+ - `outputPath` (string, optional): Path for the output file. If not provided, will be generated automatically.
129
+ - `quality` ('low' | 'medium' | 'high' | 'custom', optional): Quality preset. Default: 'medium'
130
+ - `bitrate` (number, optional): Video bitrate in bits per second (only used when quality is 'custom')
131
+ - `width` (number, optional): Output video width in pixels (only used when quality is 'custom')
132
+ - `height` (number, optional): Output video height in pixels (only used when quality is 'custom')
133
+ - `format` ('mp4' | 'mov' | 'm4v' | '3gp' | 'webm', optional): Output video format. If not specified, will be auto-detected from the input file extension (MOV → MOV, MP4 → MP4, etc.). Default: auto-detect from input file
134
+ - `onProgress` ((progress: number) => void, optional): Callback function for progress updates (0-100)
135
+
136
+ #### Returns
137
+
138
+ **`Promise<CompressionResult>`**
139
+
140
+ - `outputPath` (string): Path to the compressed video file
141
+ - `originalSize` (number): Original file size in bytes
142
+ - `compressedSize` (number): Compressed file size in bytes
143
+ - `compressionRatio` (number): Compression ratio (originalSize / compressedSize)
144
+ - `duration` (number): Duration of the compression process in milliseconds
145
+
146
+ ## Platform Support
147
+
148
+ ### iOS
149
+
150
+ - **Framework**: AVFoundation
151
+ - **Supported Formats**: MP4, MOV, M4V
152
+ - **Hardware Acceleration**: Yes (VideoToolbox)
153
+ - **Minimum iOS Version**: iOS 11.0+
154
+ - **Progress Callbacks**: Not supported (Capacitor limitation - would require event listeners)
155
+
156
+ ### Android
157
+
158
+ - **API**: MediaCodec, MediaMuxer
159
+ - **Supported Formats**: MP4, 3GP, WebM
160
+ - **Hardware Acceleration**: Yes (MediaCodec)
161
+ - **Minimum Android Version**: API 21 (Android 5.0)+
162
+ - **Progress Callbacks**: Not supported (Capacitor limitation - would require event listeners)
163
+
164
+ ### Electron
165
+
166
+ - **Library**: FFmpeg (via fluent-ffmpeg)
167
+ - **Supported Formats**: All formats supported by FFmpeg (MP4, MOV, M4V, 3GP, WebM, etc.)
168
+ - **FFmpeg Source**: Bundled via @ffmpeg-installer/ffmpeg or system FFmpeg
169
+
170
+ #### Electron Setup
171
+
172
+ 1. Install dependencies:
173
+ ```bash
174
+ npm install fluent-ffmpeg @ffmpeg-installer/ffmpeg
175
+ ```
176
+
177
+ 2. The plugin works automatically with Capacitor's standard plugin system. No additional registration is required. Simply import and use:
178
+
179
+ ```typescript
180
+ import { VideoCompressor } from '@honem/native-video-compressor';
181
+
182
+ // Works automatically in Electron
183
+ const result = await VideoCompressor.compressVideo({
184
+ inputPath: '/path/to/video.mp4',
185
+ quality: 'medium'
186
+ });
187
+ ```
188
+
189
+ **Note**: The plugin automatically detects the Electron platform and uses the FFmpeg-based implementation. Make sure FFmpeg is available (via `@ffmpeg-installer/ffmpeg` or system PATH).
190
+
191
+ **Important**: This plugin does not require `@capacitor-community/electron`. It uses Capacitor's standard plugin system with `WebPlugin`, which is compatible with Capacitor 6.0.0+. If you encounter issues with plugin registration in Electron, you may need to manually register it in your Electron main process (see the [Electron README](./electron/README.md) for details).
192
+
193
+ ### Web
194
+
195
+ - **Status**: Not supported
196
+ - **Reason**: Video compression requires native APIs or FFmpeg, which are not available in web browsers
197
+ - **Fallback**: Returns an error message directing users to use a native platform
198
+
199
+ ## Quality Presets
200
+
201
+ | Preset | Resolution | Bitrate | Use Case |
202
+ |--------|-----------|---------|----------|
203
+ | Low | 640x480 | 500 kbps | Maximum compression, lowest quality |
204
+ | Medium | 1280x720 | 2 Mbps | Balanced quality and file size (default) |
205
+ | High | Original | 8 Mbps | High quality, larger file size |
206
+ | Custom | User-defined | User-defined | Full control over compression parameters |
207
+
208
+ ## File Path Handling
209
+
210
+ The plugin supports various path formats:
211
+
212
+ - **Absolute paths**: `/path/to/video.mp4`
213
+ - **File URLs**: `file:///path/to/video.mp4`
214
+ - **Capacitor file paths**: `capacitor://localhost/_capacitor_file_/path/to/video.mp4`
215
+ - **Relative paths**: Resolved from the platform's default document directory
216
+
217
+ ## Error Handling
218
+
219
+ The plugin throws errors for:
220
+
221
+ - Missing input file
222
+ - Invalid file paths
223
+ - Unsupported formats
224
+ - Compression failures
225
+ - Missing FFmpeg (Electron only)
226
+
227
+ Always wrap compression calls in try-catch blocks:
228
+
229
+ ```typescript
230
+ try {
231
+ const result = await VideoCompressor.compressVideo({
232
+ inputPath: '/path/to/video.mp4',
233
+ quality: 'medium',
234
+ });
235
+ } catch (error) {
236
+ console.error('Compression failed:', error);
237
+ }
238
+ ```
239
+
240
+ ## Examples
241
+
242
+ See the [example app](../src/App.tsx) in the main project for a complete React implementation.
243
+
244
+ ## Development
245
+
246
+ ### Building the Plugin
247
+
248
+ ```bash
249
+ cd zoobook-compressor-plugin
250
+ npm install
251
+ npm run build
252
+ ```
253
+
254
+ ### Project Structure
255
+
256
+ ```
257
+ zoobook-compressor-plugin/
258
+ ├── src/ # TypeScript source
259
+ │ ├── definitions.ts # Type definitions
260
+ │ ├── index.ts # Plugin registration
261
+ │ └── web.ts # Web implementation (fallback)
262
+ ├── ios/ # iOS native code
263
+ │ └── Plugin/
264
+ │ ├── VideoCompressor.swift
265
+ │ ├── VideoCompressorPlugin.swift
266
+ │ └── Plugin.m
267
+ ├── android/ # Android native code
268
+ │ └── src/main/java/com/honem/nativevideocompressor/
269
+ │ ├── VideoCompressor.java
270
+ │ └── VideoCompressorPlugin.java
271
+ ├── electron/ # Electron implementation
272
+ │ └── src/
273
+ │ └── video-compressor.ts
274
+ └── package.json
275
+ ```
276
+
277
+ ## License
278
+
279
+ MIT
280
+
281
+ ## Contributing
282
+
283
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,31 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ android {
4
+ namespace "com.honem.nativevideocompressor"
5
+ compileSdk 34
6
+
7
+ defaultConfig {
8
+ minSdk 22
9
+ }
10
+
11
+ buildTypes {
12
+ release {
13
+ minifyEnabled false
14
+ }
15
+ }
16
+
17
+ compileOptions {
18
+ sourceCompatibility JavaVersion.VERSION_17
19
+ targetCompatibility JavaVersion.VERSION_17
20
+ }
21
+ }
22
+
23
+ repositories {
24
+ google()
25
+ mavenCentral()
26
+ }
27
+
28
+ dependencies {
29
+ implementation project(':capacitor-android')
30
+ }
31
+
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.honem.nativevideocompressor">
4
+
5
+ <!-- Permissions for file access -->
6
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
7
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
8
+ android:maxSdkVersion="32" />
9
+
10
+ <!-- Hardware features for video encoding -->
11
+ <uses-feature android:name="android.hardware.camera" android:required="false" />
12
+ <uses-feature android:name="android.software.video.encoder" android:required="true" />
13
+
14
+ </manifest>
15
+