@honem/native-video-compressor 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -1,14 +1,9 @@
1
1
  # @honem/native-video-compressor
2
2
 
3
- Capacitor plugin for video compression using native platform APIs (iOS AVFoundation, Android MediaCodec, Electron FFmpeg).
3
+ Capacitor plugin for video compression using native platform APIs.
4
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
5
+ - **iOS**: AVFoundation with VideoToolbox hardware acceleration
6
+ - **Android**: MediaCodec with hardware acceleration
12
7
 
13
8
  ## Installation
14
9
 
@@ -17,267 +12,73 @@ npm install @honem/native-video-compressor
17
12
  npx cap sync
18
13
  ```
19
14
 
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
15
  ## Usage
31
16
 
32
- ### Basic Usage
33
-
34
17
  ```typescript
35
18
  import { VideoCompressor } from '@honem/native-video-compressor';
36
19
 
20
+ // Compress a video
37
21
  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
22
  inputPath: '/path/to/video.mp4',
96
23
  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
24
  });
103
- ```
104
25
 
105
- ### Custom Output Path
26
+ console.log(result.outputPath); // Path to compressed file
27
+ console.log(result.compressionRatio); // e.g., 3.5
106
28
 
107
- ```typescript
108
- await VideoCompressor.compressVideo({
109
- inputPath: '/path/to/input/video.mp4',
110
- outputPath: '/path/to/output/compressed.mp4',
111
- quality: 'medium',
112
- });
29
+ // Optional: delete temp file immediately after use
30
+ await VideoCompressor.deleteFile({ path: result.outputPath });
113
31
  ```
114
32
 
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>`
33
+ ## API
120
34
 
121
- Compresses a video file.
35
+ ### compressVideo(options)
122
36
 
123
- #### Parameters
37
+ | Option | Type | Required | Description |
38
+ |--------|------|----------|-------------|
39
+ | `inputPath` | string | Yes | Path to input video |
40
+ | `outputPath` | string | No | Output path (temp file if omitted) |
41
+ | `quality` | `'low'` \| `'medium'` \| `'high'` \| `'custom'` | No | Default: `'medium'` |
42
+ | `bitrate` | number | No | Bitrate in bps (for `'custom'` quality) |
43
+ | `width` | number | No | Output width (for `'custom'` quality) |
44
+ | `height` | number | No | Output height (for `'custom'` quality) |
45
+ | `format` | `'mp4'` \| `'mov'` \| `'m4v'` \| `'3gp'` \| `'webm'` | No | Default: same as input |
124
46
 
125
- **`options`** (CompressionOptions)
47
+ **Returns:**
126
48
 
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)
49
+ | Property | Type | Description |
50
+ |----------|------|-------------|
51
+ | `outputPath` | string | Path to compressed file |
52
+ | `originalSize` | number | Original size in bytes |
53
+ | `compressedSize` | number | Compressed size in bytes |
54
+ | `compressionRatio` | number | originalSize / compressedSize |
55
+ | `duration` | number | Compression time in ms |
135
56
 
136
- #### Returns
57
+ ### deleteFile(options)
137
58
 
138
- **`Promise<CompressionResult>`**
59
+ When `outputPath` is not provided, compressed files are saved to the system temp directory which is automatically cleaned up by the OS. Use `deleteFile()` if you want to delete the file immediately after use.
139
60
 
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:
61
+ Deletes a file.
178
62
 
179
63
  ```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
- });
64
+ await VideoCompressor.deleteFile({ path: result.outputPath });
187
65
  ```
188
66
 
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
67
  ## Quality Presets
200
68
 
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 |
69
+ | Preset | Max Resolution | Bitrate |
70
+ |--------|---------------|---------|
71
+ | `low` | 854x480 | 800 kbps |
72
+ | `medium` | 1280x720 | 1.5 Mbps |
73
+ | `high` | Original | 8 Mbps |
74
+ | `custom` | User-defined | User-defined |
207
75
 
208
- ## File Path Handling
76
+ ## Platform Requirements
209
77
 
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
- ```
78
+ - **iOS**: 15.0+
79
+ - **Android**: API 22+ (Android 5.1)
80
+ - **Web**: Not supported
276
81
 
277
82
  ## License
278
83
 
279
84
  MIT
280
-
281
- ## Contributing
282
-
283
- Contributions are welcome! Please feel free to submit a Pull Request.
package/dist/index.js CHANGED
@@ -1,11 +1,6 @@
1
1
  import { registerPlugin } from '@capacitor/core';
2
- // Register plugin with platform-specific implementations
3
- // For Electron, the plugin will use the Electron implementation automatically
4
- // when running in an Electron environment (via Capacitor's plugin bridge)
5
2
  const VideoCompressor = registerPlugin('VideoCompressor', {
6
3
  web: () => import('./web').then(m => new m.VideoCompressorWeb()),
7
- // Electron implementation extends WebPlugin and works with Capacitor's standard plugin system
8
- // It will be automatically used when the plugin is called in an Electron environment
9
4
  });
10
5
  export * from './definitions';
11
6
  export { VideoCompressor };
package/dist/web.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
2
  export class VideoCompressorWeb extends WebPlugin {
3
3
  async compressVideo(_options) {
4
- throw new Error('Video compression is not supported in web browsers. Please use a native platform (iOS, Android, or Electron).');
4
+ throw new Error('Video compression is not supported in web browsers. Please use a native platform (iOS or Android).');
5
5
  }
6
6
  async deleteFile(_options) {
7
- throw new Error('File deletion is not supported in web browsers. Please use a native platform (iOS, Android, or Electron).');
7
+ throw new Error('File deletion is not supported in web browsers. Please use a native platform (iOS or Android).');
8
8
  }
9
9
  }
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "@honem/native-video-compressor",
3
- "version": "0.1.0",
4
- "description": "Capacitor plugin for video compression using native platform APIs (iOS AVFoundation, Android MediaCodec, Electron FFmpeg)",
3
+ "version": "0.2.1",
4
+ "description": "Capacitor plugin for video compression using native platform APIs (iOS AVFoundation, Android MediaCodec)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
8
8
  "dist/",
9
9
  "ios/",
10
10
  "android/",
11
- "electron/",
12
11
  "HonemNativeVideoCompressor.podspec"
13
12
  ],
14
13
  "scripts": {
@@ -26,8 +25,6 @@
26
25
  "native",
27
26
  "ios",
28
27
  "android",
29
- "electron",
30
- "ffmpeg",
31
28
  "mediacodec",
32
29
  "avfoundation"
33
30
  ],
@@ -55,10 +52,5 @@
55
52
  "devDependencies": {
56
53
  "@capacitor/core": "^6.2.0",
57
54
  "typescript": "~5.9.3"
58
- },
59
- "optionalDependencies": {
60
- "fluent-ffmpeg": "^2.1.2",
61
- "@ffmpeg-installer/ffmpeg": "^1.1.0",
62
- "@types/fluent-ffmpeg": "^2.1.24"
63
55
  }
64
56
  }
@@ -1,53 +0,0 @@
1
- # Electron Implementation
2
-
3
- This directory contains the Electron-specific implementation of the video compressor plugin.
4
-
5
- ## Setup
6
-
7
- To use this plugin in an Electron app, you need to:
8
-
9
- 1. Install the required dependencies:
10
- ```bash
11
- npm install fluent-ffmpeg @ffmpeg-installer/ffmpeg
12
- ```
13
-
14
- 2. Register the plugin in your Electron main process:
15
-
16
- The plugin uses Capacitor's standard plugin registration. In your Electron main process, you can register it manually if needed:
17
-
18
- ```typescript
19
- import { VideoCompressorElectron } from '@honem/native-video-compressor/electron';
20
- import { Capacitor } from '@capacitor/core';
21
-
22
- // Register the Electron implementation
23
- if (Capacitor.getPlatform() === 'electron') {
24
- // The plugin will be automatically registered when imported
25
- // If you need manual registration, you can do:
26
- const compressor = new VideoCompressorElectron();
27
- // Register with Capacitor's bridge if needed
28
- }
29
- ```
30
-
31
- Alternatively, you can use the plugin directly in your renderer process:
32
-
33
- ```typescript
34
- import { VideoCompressor } from '@honem/native-video-compressor';
35
-
36
- // The plugin will automatically use the Electron implementation
37
- // when running in an Electron environment
38
- const result = await VideoCompressor.compressVideo({
39
- inputPath: '/path/to/video.mp4',
40
- quality: 'medium'
41
- });
42
- ```
43
-
44
- **Note**: The plugin automatically detects the Electron platform and uses the appropriate implementation. No additional registration is typically required.
45
-
46
- ## FFmpeg
47
-
48
- The Electron implementation uses FFmpeg for video compression. It will:
49
- 1. First try to use the bundled FFmpeg from `@ffmpeg-installer/ffmpeg`
50
- 2. Fall back to system FFmpeg if available in PATH
51
-
52
- Make sure FFmpeg is available either via the npm package or installed on the system.
53
-
@@ -1,4 +0,0 @@
1
- // Electron plugin registration
2
- // This file is used when the plugin is loaded in an Electron environment
3
- export { VideoCompressorElectron } from './video-compressor';
4
-
@@ -1,202 +0,0 @@
1
- import type { VideoCompressorPlugin, CompressionOptions, CompressionResult, DeleteFileOptions, DeleteFileResult } from '../../src/definitions';
2
- import { WebPlugin } from '@capacitor/core';
3
- import * as ffmpeg from 'fluent-ffmpeg';
4
- import * as ffmpegInstaller from '@ffmpeg-installer/ffmpeg';
5
- import * as path from 'path';
6
- import * as fs from 'fs';
7
- import * as os from 'os';
8
- import { promisify } from 'util';
9
-
10
- const stat = promisify(fs.stat);
11
- const unlink = promisify(fs.unlink);
12
-
13
- let ffmpegPath: string | null = null;
14
-
15
- try {
16
- ffmpegPath = ffmpegInstaller.path;
17
- ffmpeg.setFfmpegPath(ffmpegPath);
18
- } catch {
19
- try {
20
- ffmpegPath = 'ffmpeg';
21
- } catch {
22
- console.warn('FFmpeg not found. Please install FFmpeg or use @ffmpeg-installer/ffmpeg');
23
- }
24
- }
25
-
26
- export class VideoCompressorElectron extends WebPlugin implements VideoCompressorPlugin {
27
- constructor() {
28
- super();
29
- }
30
-
31
- async compressVideo(options: CompressionOptions): Promise<CompressionResult> {
32
- if (!ffmpegPath) {
33
- throw new Error('FFmpeg is not available. Please install FFmpeg or use @ffmpeg-installer/ffmpeg');
34
- }
35
-
36
- const startTime = Date.now();
37
- const inputPath = this.resolveFilePath(options.inputPath);
38
- const outputPath = options.outputPath
39
- ? this.resolveFilePath(options.outputPath)
40
- : this.generateTempOutputPath(options.format || 'mp4');
41
-
42
- try {
43
- await stat(inputPath);
44
- } catch {
45
- throw new Error(`Input file not found: ${inputPath}`);
46
- }
47
-
48
- const inputStats = await stat(inputPath);
49
- const originalSize = inputStats.size;
50
-
51
- const { targetBitrate, targetWidth, targetHeight, videoCodec, audioCodec, format } =
52
- this.getCompressionParams(options);
53
-
54
- try {
55
- await stat(outputPath);
56
- await unlink(outputPath);
57
- } catch {
58
- // File doesn't exist, which is fine
59
- }
60
-
61
- return new Promise((resolve, reject) => {
62
- const command = ffmpeg(inputPath)
63
- .videoCodec(videoCodec)
64
- .audioCodec(audioCodec)
65
- .outputOptions([
66
- '-preset fast',
67
- '-movflags +faststart',
68
- ]);
69
-
70
- if (targetBitrate) {
71
- command.videoBitrate(targetBitrate);
72
- }
73
-
74
- if (targetWidth && targetHeight) {
75
- command.size(`${targetWidth}x${targetHeight}`);
76
- }
77
-
78
- command.format(format);
79
- command.output(outputPath);
80
-
81
- command.on('error', (error) => {
82
- reject(new Error(`FFmpeg error: ${error.message}`));
83
- });
84
-
85
- command.on('end', async () => {
86
- try {
87
- const outputStats = await stat(outputPath);
88
- const compressedSize = outputStats.size;
89
- const duration = Date.now() - startTime;
90
- const compressionRatio = originalSize / compressedSize;
91
-
92
- resolve({
93
- outputPath,
94
- originalSize,
95
- compressedSize,
96
- compressionRatio,
97
- duration,
98
- });
99
- } catch (error) {
100
- reject(new Error(`Failed to get output file stats: ${error}`));
101
- }
102
- });
103
-
104
- command.run();
105
- });
106
- }
107
-
108
- async deleteFile(options: DeleteFileOptions): Promise<DeleteFileResult> {
109
- try {
110
- const filePath = this.resolveFilePath(options.path);
111
- await stat(filePath);
112
- await unlink(filePath);
113
- return { success: true };
114
- } catch {
115
- return { success: false };
116
- }
117
- }
118
-
119
- private resolveFilePath(filePath: string): string {
120
- if (filePath.startsWith('file://')) {
121
- return filePath.replace('file://', '');
122
- }
123
-
124
- if (path.isAbsolute(filePath)) {
125
- return filePath;
126
- }
127
-
128
- return path.resolve(process.cwd(), filePath);
129
- }
130
-
131
- private generateTempOutputPath(format: string): string {
132
- const tempDir = os.tmpdir();
133
- const extension = this.getFileExtension(format);
134
- const uniqueName = `compressed_${Date.now()}.${extension}`;
135
- return path.join(tempDir, uniqueName);
136
- }
137
-
138
- private getFileExtension(format: string): string {
139
- switch (format.toLowerCase()) {
140
- case 'mov':
141
- return 'mov';
142
- case 'm4v':
143
- return 'm4v';
144
- case 'webm':
145
- return 'webm';
146
- case '3gp':
147
- return '3gp';
148
- case 'mp4':
149
- default:
150
- return 'mp4';
151
- }
152
- }
153
-
154
- private getCompressionParams(options: CompressionOptions) {
155
- let targetBitrate: number | undefined;
156
- let targetWidth: number | undefined;
157
- let targetHeight: number | undefined;
158
- let videoCodec = 'libx264';
159
- let audioCodec = 'aac';
160
- const format = options.format || 'mp4';
161
-
162
- switch (options.quality) {
163
- case 'low':
164
- targetBitrate = 800;
165
- targetWidth = 854;
166
- targetHeight = 480;
167
- break;
168
- case 'high':
169
- targetBitrate = options.bitrate ? options.bitrate / 1000 : 8000;
170
- targetWidth = options.width;
171
- targetHeight = options.height;
172
- break;
173
- case 'custom':
174
- targetBitrate = options.bitrate ? options.bitrate / 1000 : 2000;
175
- targetWidth = options.width;
176
- targetHeight = options.height;
177
- break;
178
- default: // 'medium'
179
- targetBitrate = 1500;
180
- targetWidth = 1280;
181
- targetHeight = 720;
182
- break;
183
- }
184
-
185
- if (format === 'webm') {
186
- videoCodec = 'libvpx-vp9';
187
- audioCodec = 'libopus';
188
- } else if (format === '3gp') {
189
- videoCodec = 'h263';
190
- audioCodec = 'amr_nb';
191
- }
192
-
193
- return {
194
- targetBitrate,
195
- targetWidth,
196
- targetHeight,
197
- videoCodec,
198
- audioCodec,
199
- format,
200
- };
201
- }
202
- }