# Mediasoup-client-android16kb **Repository Path**: swei_android/mediasoup-client-android16kb ## Basic Information - **Project Name**: Mediasoup-client-android16kb - **Description**: mediasoup-client-android 重新构建AGP 9.x + Java 21 兼容性修复,16KB对齐。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-11 - **Last Updated**: 2026-06-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README <<<<<<< HEAD # mediasoup-client-android [![Codacy Badge](https://api.codacy.com/project/badge/Grade/0e44257c6bcf47df9163e88fa7d5125a)](https://app.codacy.com/gh/haiyangwu/mediasoup-client-android?utm_source=github.com&utm_medium=referral&utm_content=haiyangwu/mediasoup-client-android&utm_campaign=Badge_Grade_Settings) [![maven][shield-mediasoup-client-android]][maven-mediasoup-client-android] mediasoup android client side library https://mediasoup.org ## Getting Started ### Setting up the dependency Include `mediasoup-client-android` into your project, for example, as a Gradle compile dependency: ```groovy implementation 'io.github.haiyangwu:mediasoup-client:3.4.0' ``` ### Example * Initialize `MediasoupClient` ```Java MediasoupClient.initialize(getApplicationContext()); ``` * Create `Device` and load `routerRtpCapabilities` ```Java Device mMediasoupDevice = new Device(); // ... // routerRtpCapabilities, the response of request `getRouterRtpCapabilities` from mediasoup-demo server mMediasoupDevice.load(routerRtpCapabilities, null) ``` * Create `SendTransport` and produce `MediaStreamTrack` ```Java // ... // res, the response of request `createWebRtcTransport` from mediasoup-demo server JSONObject info = new JSONObject(res); String id = info.optString("id"); String iceParameters = info.optString("iceParameters"); String iceCandidates = info.optString("iceCandidates"); String dtlsParameters = info.optString("dtlsParameters"); String sctpParameters = info.optString("sctpParameters"); SendTransport mSendTransport = mMediasoupDevice.createSendTransport( sendTransportListener, id, iceParameters, iceCandidates, dtlsParameters); // ... // mLocalVideoTrack, created by `org.webrtc.PeerConnectionFactory` Producer mCamProducer = mSendTransport.produce( producer -> { Logger.e(TAG, "onTransportClose(), camProducer"); }, mLocalVideoTrack, null, null, null); ``` * Create `RecvTransport` and consume `MediaStreamTrack` ```Java // ... // res, the response of request `createWebRtcTransport` from mediasoup-demo server JSONObject info = new JSONObject(res); String id = info.optString("id"); String iceParameters = info.optString("iceParameters"); String iceCandidates = info.optString("iceCandidates"); String dtlsParameters = info.optString("dtlsParameters"); String sctpParameters = info.optString("sctpParameters"); RecvTransport mRecvTransport = mMediasoupDevice.createRecvTransport( recvTransportListener, id, iceParameters, iceCandidates, dtlsParameters); // ... // request, the request `newConsumer` from mediasoup-demo server JSONObject data = request.getData(); String peerId = data.optString("peerId"); String producerId = data.optString("producerId"); String id = data.optString("id"); String kind = data.optString("kind"); String rtpParameters = data.optString("rtpParameters"); String type = data.optString("type"); String appData = data.optString("appData"); Consumer consumer = mRecvTransport.consume( c -> { Logger.w(TAG, "onTransportClose for consume"); }, id, producerId, kind, rtpParameters, appData); ``` ## Dependencies * [libmediasoupclient][libmediasoupclient] mediasoup client side C++ library which supported by mediasoup team * [webrtc-android-build][webrtc-android-build] my personal `webrtc` android prebuilt static library which may be compiled with some patch ## Demo Project [mediasoup-demo-android][mediasoup-demo-android] ## Bugs and Feedback For bugs, feature requests, and discussion please use [GitHub Issues][issues]. ## Author Haiyang Wu([@haiyangwu](https://github.com/haiyangwu/) at Github) ## License [MIT](./LICENSE) [maven-mediasoup-client-android]: https://ossindex.sonatype.org/component/pkg:maven/io.github.haiyangwu/mediasoup-client [shield-mediasoup-client-android]: https://img.shields.io/maven-central/v/io.github.haiyangwu/mediasoup-client [libmediasoupclient]: https://github.com/versatica/libmediasoupclient [webrtc-android-build]: https://github.com/haiyangwu/webrtc-android-build [mediasoup-demo-android]: https://github.com/haiyangwu/mediasoup-demo-android [issues]: https://github.com/haiyangwu/mediasoup-client-android/issues ======= # mediasoup-client-android 构建修复历程 ## 第一阶段:AGP 9.x + Java 21 兼容性 | # | 文件 | 修改内容 | 原因 | |---|------|----------|------| | 1 | `mediasoup-client/build.gradle` | `sourceCompatibility VERSION_8` → `VERSION_11` | Java 21 不再支持 source/target 8 | | 2 | 同上 | 添加 `namespace 'org.mediasoup.droid'` | AGP 9.x 强制要求 | | 3 | 同上 | `ndkVersion` 从 `22.0.7026061` 改为 `27.0.12077973` | NDK 22 未安装,使用已安装版本 | | 4 | 同上 | 添加 `version "4.1.2"` 明确指定 CMake 版本 | SDK 仅有 CMake 4.1.2 | | 5 | 同上 | `from components.release` → `from components.findByName("release")` | AGP 9.x 多变体构建 API 变更 | | 6 | `mediasoup-client/CMakeLists.txt` | `cmake_minimum_required(VERSION 3.0)` → `VERSION 3.5` | CMake 4.x 要求 ≥ 3.5 | ## 中介操作:依赖准备 | # | 操作 | 说明 | |---|------|------| | 7 | 清理 Gradle transform 缓存 | 修复 `libwebrtc.jar zip END header not found` | | 8 | `git lfs pull` | 下载所有 4 个 ABI 的 `libwebrtc.a`(每个 100-140MB) | | 9 | 克隆 `webrtc-mirror` (m94) 到 `deps/webrtc/src` | 提供 WebRTC 源码头文件 | | 10 | 克隆 `libmediasoupclient` (3.4.0) | 主 C++ 依赖 | ## 第二阶段:CMake 4.x + 链接兼容性 | # | 文件 | 修改内容 | 原因 | |---|------|----------|------| | 11 | `deps/libmediasoupclient/deps/libsdptransform/CMakeLists.txt` | `cmake_minimum_required VERSION 3.0` → `VERSION 3.5` | CMake 4.x 要求 ≥ 3.5 | | 12 | 同上 | `subdirs(test readme-helper)` → 条件化 `if/endif + add_subdirectory()` | `subdirs()` 在 CMake 4.x 中已移除 | | 13 | 重新克隆 `abseil-cpp` | HEAD → tag `20210324.0` | HEAD 版本要求 C++17,项目用 C++14 | | 14 | `mediasoup-client/CMakeLists.txt` | 添加 4 个 abseil `.cc` 源文件到编译目标 | 链接器找不到 `throw_bad_optional_access`、`ThrowStdOutOfRange`、`EqualsIgnoreCase`、`memcasecmp` 等符号 | | 15 | `deps/webrtc/src/third_party/abseil-cpp/absl/base/options.h` | `ABSL_OPTION_USE_INLINE_NAMESPACE 1` → `0` | 预编译 `libwebrtc.a` 不使用 `lts_20210324` 内联命名空间,导致符号名不匹配 | ## 第三阶段:清理警告 | # | 文件 | 修改内容 | 原因 | |---|------|----------|------| | 16 | `gradle.properties` | 删除 `android.enableJetifier=true` | AGP 10 将移除,项目已使用 AndroidX 无需 Jetifier | ## 第四阶段:运行时 JNI 符号丢失 | # | 文件 | 修改内容 | 原因 | |---|------|----------|------| | 17 | `mediasoup-client/CMakeLists.txt` | 添加 `-Wl,--whole-archive` 包裹 `libwebrtc.a` | 静态库中 JNI 函数未被 C++ 代码引用,链接器按需链接丢弃了它们,导致运行时 `UnsatisfiedLinkError` | | 18 | 同上 | 注释掉之前手动添加的 4 个 abseil `.cc` 源文件 | `--whole-archive` 已包含这些符号,避免重复定义 | | 19 | `deps/libmediasoupclient/CMakeLists.txt` | 还原为原始状态 | 之前添加的 `--whole-archive` 与主 CMakeLists.txt 重复,导致重复符号链接错误 | ## 第五阶段:Google Play 16KB 页大小兼容 | # | 文件 | 修改内容 | 原因 | |---|------|----------|------| | 20 | `mediasoup-client/CMakeLists.txt` | 添加 `target_link_options` 设置 `-Wl,-z,max-page-size=16384` 和 `-Wl,-z,common-page-size=16384` | Google Play 要求 2025.11 起新应用/更新的 Android 15+ 设备中,`.so` 的 LOAD 段必须 16KB 对齐 | ## 核心根因关系图 ``` ┌─────────────────────┐ │ Windows + CMake 4.x │ │ + AGP 9.x + JDK 21 │ └─────────┬───────────┘ │ ┌──────────────────┼──────────────────┐ ▼ ▼ ▼ Java 8 → 11 CMake 3.0 → 3.5 subdirs() 已移除 (JDK 21 不兼容) (CMake 4.x 要求) (CMake 4.x 移除) │ │ │ │ ┌─────┴─────┐ │ │ ▼ ▼ │ │ libsdptransform 主 CMakeLists │ │ 已修复 ✅ 已修复 ✅ │ ▼ ▼ abseil-cpp HEAD (C++17) libwebrtc.a 预编译符号 → 降级至 20210324.0 (C++14) 与 abseil LTS 命名空间不匹配 │ → 禁用内联命名空间 ▼ 链接缺失符号 (throw_bad_optional_access 等) → 编译 abseil .cc 源文件 ``` ## 最终结果 **`BUILD SUCCESSFUL in 2m 7s`** ✅ ## 编译命令 #### 在项目根目录下执行: ```sh # 生成 Debug 版本 ./gradlew :mediasoup-client:assembleDebug # 生成 Release 版本 ./gradlew :mediasoup-client:assembleRelease ``` #### 仅编译指定 ABI: ```sh # 仅 arm64-v8a debug ./gradlew :mediasoup-client:buildCMakeDebug[arm64-v8a] # 仅 arm64-v8a debug ./gradlew :mediasoup-client:buildCMakeDebug[arm64-v8a] # 仅 x86 debug ./gradlew :mediasoup-client:buildCMakeDebug[x86] # 仅 x86_64 debug ./gradlew :mediasoup-client:buildCMakeDebug[x86_64] # 仅 armeabi-v7a debug ./gradlew :mediasoup-client:buildCMakeDebug[armeabi-v7a] # 仅 arm64-v8a release (注意:AGP 将 release 映射为 RelWithDebInfo) ./gradlew :mediasoup-client:buildCMakeRelWithDebInfo[arm64-v8a] # 仅 x86_64 release ./gradlew :mediasoup-client:buildCMakeRelWithDebInfo[x86_64] # 仅 armeabi-v7a release ./gradlew :mediasoup-client:buildCMakeRelWithDebInfo[armeabi-v7a] # 仅 x86 release ./gradlew :mediasoup-client:buildCMakeRelWithDebInfo[x86] ``` #### Native 动态库 (.so) - `Debug version` - `mediasoup-client/build/intermediates/cxx/Debug//obj/armeabi-v7a/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/Debug//obj/arm64-v8a/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/Debug//obj/x86/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/Debug//obj/x86_64/libmediasoupclient.so` - `Release version` (实际 CMake 构建类型为 `RelWithDebInfo`) - `mediasoup-client/build/intermediates/cxx/RelWithDebInfo//obj/armeabi-v7a/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/RelWithDebInfo//obj/arm64-v8a/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/RelWithDebInfo//obj/x86/libmediasoupclient.so` - `mediasoup-client/build/intermediates/cxx/RelWithDebInfo//obj/x86_64/libmediasoupclient.so` #### AAR 包(最终产物) - `Debug version` - `mediasoup-client/build/outputs/aar/mediasoup-client-debug.aar` - `Release version` - `mediasoup-client/build/outputs/aar/mediasoup-client-release.aar` >>>>>>> a922e3267ac340eefb47e33c94cde7a60eb901e7