munim-ffmpeg 0.3.0 → 0.4.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/README.md CHANGED
@@ -68,6 +68,7 @@
68
68
  - [📚 Documentation](#-documentation)
69
69
  - [🚀 Features](#-features)
70
70
  - [Platform support matrix](#platform-support-matrix)
71
+ - [Where this is verified](#where-this-is-verified)
71
72
  - [Bundled FFmpeg builds](#bundled-ffmpeg-builds)
72
73
  - [📦 Installation](#-installation)
73
74
  - [Working with media paths](#working-with-media-paths)
@@ -134,6 +135,35 @@
134
135
 
135
136
  Codec availability is determined by the native FFmpeg builds described in [Bundled FFmpeg builds](#bundled-ffmpeg-builds). Do not assume every FFmpeg codec or external library is present.
136
137
 
138
+ ## Where this is verified
139
+
140
+ Every release runs the example's 24-check device suite. For 0.3.x:
141
+
142
+ | Target | Result |
143
+ | --- | --- |
144
+ | iPad Air (M3), iOS 26 | 24/24 |
145
+ | iOS Simulator, arm64 | 24/24 |
146
+ | Galaxy A14 5G, arm64-v8a | 24/24 |
147
+ | Android emulator, arm64 | 13/24 — see below |
148
+ | Android `armeabi-v7a`, `x86_64` | Built and statically checked, not executed |
149
+
150
+ `x86_64` cannot be run on an Apple Silicon machine: the Android emulator refuses non-native system images, and no x86_64 hardware was available. Both remaining ABIs were verified to be correct ELF binaries with the right architecture, the expected JNI exports, only system libraries unresolved, and the same FFmpeg 9.0.1 and codec set as arm64.
151
+
152
+ ### Android emulators cannot encode video
153
+
154
+ An Android emulator has no working MediaCodec **encoder**. `h264_mediacodec` and `hevc_mediacodec` report success and produce a file containing no frames, so anything downstream of an encode fails. Everything else — audio encoding, filters, FFprobe, muxing, cancellation, protocols — works normally there.
155
+
156
+ This is an emulator limitation, not a package one, but it is worth knowing before debugging: **test video encoding on a physical device**.
157
+
158
+ `pickEncoder` cannot detect it, because MediaCodec *is* present in an emulator — it just does not work. When you need encoding to succeed regardless of environment, ask for the software encoder by name:
159
+
160
+ ```typescript
161
+ // Deterministic anywhere: emulators, CI, older devices.
162
+ await execute(['-y', '-i', input, '-c:v', 'libopenh264', '-pix_fmt', 'yuv420p', output])
163
+ ```
164
+
165
+ `libopenh264`, `mpeg4` and `libvpx-vp9` are all software encoders and work everywhere.
166
+
137
167
  ## Bundled FFmpeg builds
138
168
 
139
169
  Both platforms run **FFmpeg 9.0.1**, built from [ffmpeg.org](https://www.ffmpeg.org/) by the scripts in [`scripts/ffmpeg/`](./scripts/ffmpeg). There is no FFmpegKit here: that project was retired in 2025 and pinned to FFmpeg 6.0.
@@ -146,7 +176,7 @@ Both platforms run **FFmpeg 9.0.1**, built from [ffmpeg.org](https://www.ffmpeg.
146
176
  | TLS | SecureTransport | mbedTLS |
147
177
  | Minimum | iOS 15.1 | API 24, 16 KB pages |
148
178
 
149
- Linked libraries, identical on both: **LAME** (MP3), **Opus**, **libvpx** (VP8/VP9), **dav1d** (AV1 decoding), plus everything FFmpeg builds natively.
179
+ Linked libraries, identical on both: **LAME** (MP3), **Opus**, **libvpx** (VP8/VP9), **dav1d** (AV1 decoding), **openh264** (software H.264), plus everything FFmpeg builds natively.
150
180
 
151
181
  FFmpeg's own `ffmpeg` and `ffprobe` tools are compiled to run inside your app process, so the argument arrays you pass are handled by the real command-line code paths rather than a reimplementation.
152
182
 
@@ -154,20 +184,26 @@ FFmpeg's own `ffmpeg` and `ffprobe` tools are compiled to run inside your app pr
154
184
 
155
185
  Verified by running the example's device suite: iOS reports 186 encoders, Android 184. Everything FFmpeg builds natively (`aac`, `alac`, `flac`, `mpeg4`, `mjpeg`, `png`, `gif`, `pcm_*`, …) is on both, as are `libmp3lame`, `libopus`, `libvpx`, and `libvpx-vp9`.
156
186
 
157
- H.264 and HEVC come from the platform's hardware encoder, which is faster and smaller than bundling x264and keeps the package LGPL:
187
+ H.264 and HEVC come from the platform's hardware encoder, which is faster and uses less power than a software encoder. `libopenh264` is there as a software H.264 fallback for anywhere hardware encoding is unavailable an emulator, for instance:
158
188
 
159
189
  | Encoder | iOS | Android |
160
190
  | --- | --- | --- |
161
191
  | `h264_videotoolbox`, `hevc_videotoolbox`, `prores_videotoolbox` | ✅ | ❌ |
162
192
  | `h264_mediacodec`, `hevc_mediacodec`, `vp8_mediacodec`, `vp9_mediacodec` | ❌ | ✅ |
163
193
  | `aac_at`, `alac_at` (AudioToolbox) | ✅ | ❌ |
194
+ | `libopenh264` (H.264, software) | ✅ | ✅ |
164
195
 
165
196
  Resolve the name at runtime instead of branching on `Platform.OS`:
166
197
 
167
198
  ```typescript
168
199
  import { execute, pickEncoder } from 'munim-ffmpeg'
169
200
 
170
- const h264 = await pickEncoder(['h264_videotoolbox', 'h264_mediacodec'])
201
+ // Hardware first, software as the fallback.
202
+ const h264 = await pickEncoder([
203
+ 'h264_videotoolbox',
204
+ 'h264_mediacodec',
205
+ 'libopenh264',
206
+ ])
171
207
  if (!h264) throw new Error('No H.264 encoder in this build')
172
208
 
173
209
  await execute(['-y', '-i', inputPath, '-c:v', h264, outputPath])
@@ -595,7 +631,9 @@ if (result.success) {
595
631
 
596
632
  The JavaScript, TypeScript, Swift, Kotlin, C core, and generated Nitro bridge in this repository are Apache-2.0.
597
633
 
598
- The bundled FFmpeg 9.0.1 is **LGPLv3**, on both platforms. It is configured without `--enable-gpl`, so no x264, x265, xvid, or vid.stab: H.264 and HEVC encoding come from VideoToolbox and MediaCodec instead. The external libraries it does link are LAME (LGPL), Opus (BSD), libvpx (BSD), dav1d (BSD), and mbedTLS (Apache-2.0) on Android.
634
+ The bundled FFmpeg 9.0.1 is **LGPLv3**, on both platforms. It is configured without `--enable-gpl`, so no x264, x265, xvid, or vid.stab. The external libraries it links are LAME (LGPL), Opus (BSD), libvpx (BSD), dav1d (BSD), openh264 (BSD 2-clause), and mbedTLS (Apache-2.0) on Android.
635
+
636
+ > **A note on H.264 patents.** Hardware encoders are covered by the licences device manufacturers already pay for. Software H.264 encoding through `libopenh264` is not: Cisco's royalty coverage applies to *their* prebuilt binary, and this package builds openh264 from source. If you ship software H.264 encoding at scale, check where you stand with AVC licensing. Hardware encoders avoid the question entirely, which is why `pickEncoder` should list them first.
599
637
 
600
638
  In practice that means your application does **not** inherit GPL obligations. LGPL still applies: the FFmpeg libraries are linked and their license and notices must be conveyed with your app, and users must be able to relink against a modified FFmpeg. The exact configuration used is recorded in [`scripts/ffmpeg/build-ios.sh`](./scripts/ffmpeg/build-ios.sh) and [`build-android.sh`](./scripts/ffmpeg/build-android.sh), and the binaries can be reproduced from them.
601
639
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "munim-ffmpeg",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Fast FFmpeg and FFprobe for Expo and React Native, powered by Nitro Modules",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "archive": "munim-ffmpeg-binaries.tar.gz",
3
- "sha256": "5d3a286633c584ffb2ef9dec091695f5ba8f8db88187058df7143ef258e15beb",
3
+ "sha256": "e78e41e80741ec747d148e00749e2f689b96b1b7efa51dc7d6f65d4fc0ab7463",
4
4
  "ffmpeg": "9.0.1"
5
5
  }