- Gate buildFfmpegJni + jniLibs packaging on `ux: enable_ffmpeg` in the consuming app's pubspec (default off) -- no LGPL / H.264-patent exposure unless explicitly enabled - appInfoBuilder generates kUxEnableFfmpeg from the same flag so apps register the FFmpeg LGPL notice eagerly, pubspec-only (no dart-define) - Add registerFfmpegLicense() + bundled LGPL-2.1 text asset - FFmpeg compliance docs (LICENSES-3RDPARTY.md, android/ffmpeg/README.md) - Network video streaming: XVideoPlayerController.network
3.7 KiB
ux — Third-Party Licenses & Compliance
ux can bundle one component with distribution obligations: FFmpeg, used
as a software H.264 video decoder on Android. It is opt-in and disabled by
default — only apps that enable it ship it and inherit the obligation:
ux:
enable_ffmpeg: true
That pubspec flag is the single source of truth: Gradle reads it for the
native build, and ux's build_runner builder generates a kUxEnableFfmpeg
constant from it into the app's app_info.g.dart, which gates
registerFfmpegLicense() at startup — so the in-app LGPL notice follows
automatically, eagerly, with no --dart-define.
Apps that enable it need to (a) surface a license UI and (b) be able to honor the source offer below; apps that leave it disabled have no FFmpeg obligation (and the in-app notice never appears).
FFmpeg (LGPL-2.1) — Android only
What and where
Compiled from source into libffmpegJNI.so per ABI and loaded at runtime via
System.loadLibrary — an ExoPlayer/Media3 fallback decode-only renderer.
Not a pub/Dart dependency. iOS/macOS use AVFoundation → no FFmpeg, no
obligation there.
- Build wiring: android/ffmpeg/ —
build_ffmpeg.sh,CMakeLists.txt,ffmpeg_jni.cc,README.md,LICENSE-FFMPEG.txt. - Attribution: lib/builder.dart generates a
kUxEnableFfmpegconstant from the app'sux: enable_ffmpegpubspec flag intoapp_info.g.dart; the app gates registerFfmpegLicense() on it at startup (if (kUxEnableFfmpeg) registerFfmpegLicense();). So a build with the flag off registers nothing, and an enabled build shows the notice eagerly. Idempotent. - Bundled LGPL text asset:
assets/licenses/ffmpeg_LGPL-2.1.txt.
Versions (pinned)
- FFmpeg
release/6.0(upstreamgit.ffmpeg.org) - Media3
1.9.2(JNI/renderer skeleton)
License posture
- LGPL v2.1, dynamic boundary (separate, replaceable
.so) → no copyleft on the consuming app. - Built decode-only (H.264 decoder, no encoders) and WITHOUT
--enable-gpl/--enable-nonfree→ LGPL-only. Seebuild_ffmpeg.sh.
How we comply (LGPL-2.1)
- Attribution + license text — registered via
registerFfmpegLicense(), shown in any consuming app's license UI. ✅ - Corresponding source — we make the FFmpeg
release/6.0source plus the build/link scripts (build_ffmpeg.sh,CMakeLists.txt,ffmpeg_jni.cc) available on request for ≥3 years. This does NOT include the application's own source code — only the LGPL library and the scripts that compile/link it. Contact: alex@swipelab.co. → Each release: archive the matching FFmpeg source tarball + the scripts. - Relink right (LGPL §6) —
libffmpegJNI.sois a standalone, user-rebuildable shared library; sources + script are here, so a modified FFmpeg can be rebuilt and swapped in. ✅ - Do not taint — never add
--enable-gpl/--enable-nonfreeor GPL-only codecs (x264, x265, …).
Patent note (for legal — separate from copyright)
FFmpeg's H.264 decoder code is LGPL, but the H.264/AVC standard is patent-encumbered (Via LA pool, formerly MPEG-LA). We ship a software AVC decoder — a patent/commercial matter for counsel, not an open-source or store-policy issue. Exposure is limited to decode (no encoder shipped).
Release checklist
- FFmpeg/Media3 tags unchanged, or doc + archived source updated if bumped.
- Build still omits
--enable-gpl/--enable-nonfree; decode-only. registerFfmpegLicense()reachable (auto on video, or eager at startup).- FFmpeg
release/6.0source tarball + scripts archived for this version.