@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.
- package/HonemNativeVideoCompressor.podspec +15 -0
- package/README.md +283 -0
- package/android/build.gradle +31 -0
- package/android/src/main/AndroidManifest.xml +15 -0
- package/android/src/main/java/com/honem/nativevideocompressor/VideoCompressor.java +488 -0
- package/android/src/main/java/com/honem/nativevideocompressor/VideoCompressorPlugin.java +72 -0
- package/dist/definitions.d.ts +76 -0
- package/dist/definitions.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -0
- package/dist/web.d.ts +6 -0
- package/dist/web.js +9 -0
- package/electron/README.md +53 -0
- package/electron/src/index.ts +4 -0
- package/electron/src/video-compressor.ts +202 -0
- package/ios/Plugin/Plugin.m +7 -0
- package/ios/Plugin/VideoCompressor.swift +378 -0
- package/ios/Plugin/VideoCompressorPlugin.swift +61 -0
- package/ios/VideoCompressor.podspec +14 -0
- package/package.json +64 -0
|
@@ -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
|
+
|