docs(android): 用实现说明替换阶段三占位 README
This commit is contained in:
@@ -1,48 +1,99 @@
|
||||
# opendance-android
|
||||
|
||||
OpenDance Studio **阶段三**:Android 辅助 App(Kotlin + MediaPipe 端侧推理)。
|
||||
OpenDance Studio **阶段三**:Android 辅助 App(Kotlin + CameraX + MediaPipe 端侧推理)。
|
||||
|
||||
> **状态:占位仓库**。按《DSH 开发文档:OpenDance Studio》的开发顺序
|
||||
> (Web 服务端 → Windows 客户端 → Android 辅助 App),本仓库将在阶段二
|
||||
> (`opendance-windows`)冻结 WebSocket 关键点协议后开始开发。
|
||||
用手机摄像头做**端侧**姿态推理,把 33 个骨骼关键点通过 WebSocket 推给 Windows 客户端,
|
||||
由后者驱动 VRM 角色并 DTW 实时评分。
|
||||
|
||||
## 计划技术栈
|
||||
> **画面不离开设备**。通过网络发送的只有 33 个关键点坐标,不含任何图像数据。
|
||||
|
||||
## 状态
|
||||
|
||||
**阶段三已完成**:T-AND-001 → T-AND-009 全部落地。
|
||||
|
||||
| 验收项 | 结果 |
|
||||
|---|---|
|
||||
| 单元测试 | ✓ **25 项全部通过**(JVM,无需设备) |
|
||||
| **跨端金标准** | ✓ Kotlin 序列化器与 Web 端 TypeScript 实现**逐位一致** |
|
||||
| `./gradlew assembleRelease` | ✓ 生成**已签名** APK(28.6 MB) |
|
||||
| 签名校验 | ✓ `apksigner` 退出码 0,v2 方案,CN=OpenDance Studio Dev |
|
||||
| 包信息 | ✓ `com.opendance.studio` v0.1.0,minSdk 29(Android 10+)/ targetSdk 34 |
|
||||
| 模型随包分发 | ✓ `assets/pose_landmarker_lite.task` 5.7 MB(Stored 未压缩) |
|
||||
| ABI 覆盖 | ✓ arm64-v8a + armeabi-v7a(debug 额外含 x86/x86_64) |
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
export JAVA_HOME=/path/to/jdk17 # AGP 8.7.3 要求
|
||||
export ANDROID_HOME=/path/to/android-sdk
|
||||
|
||||
bash build/gen-keystore.sh # 生成发布签名(首次;不入库,请自行备份)
|
||||
bash build/verify.sh # 单元测试 → 构建 → 产物校验
|
||||
bash build/build-apk.sh all # 仅构建 debug + release
|
||||
bash build/package-release.sh # 打发布包
|
||||
```
|
||||
|
||||
详细使用说明见 [`README.txt`](README.txt),工程约束见 [`DSH.md`](DSH.md)。
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 组件 | 选型 |
|
||||
|---|---|
|
||||
| 语言 | Kotlin |
|
||||
| 相机 | CameraX (Apache 2.0) |
|
||||
| 推理 | MediaPipe Pose (Apache 2.0) |
|
||||
| 通信 | OkHttp WebSocket (Apache 2.0) |
|
||||
| UI | Jetpack Compose (Apache 2.0) |
|
||||
| 语言 | Kotlin 2.0.21 |
|
||||
| 构建 | AGP 8.7.3 + Gradle 8.9 + JDK 17 |
|
||||
| 相机 | CameraX 1.4.0 |
|
||||
| 推理 | MediaPipe Tasks Vision 0.10.35 |
|
||||
| 通信 | OkHttp 4.12.0 |
|
||||
| UI | Jetpack Compose(BOM 2024.10.01,Material3) |
|
||||
|
||||
## 计划任务
|
||||
## 数据流
|
||||
|
||||
`T-AND-001` 骨架 → `T-AND-002` CameraX 采集 → `T-AND-003` MediaPipe Pose 推理 →
|
||||
`T-AND-004` 33 点 → 239 字节帧序列化 → `T-AND-005` WebSocket 推流 + 自动重连 →
|
||||
`T-AND-006` 连接页 + 主机发现 → `T-AND-007` 运行页 + 状态指示 →
|
||||
`T-AND-008` 关于页 + 开源声明 → `T-AND-009` APK 打包
|
||||
```
|
||||
CameraX(ImageAnalysis) ──▶ MediaPipe PoseLandmarker(端侧推理)
|
||||
│ 33 点归一化坐标
|
||||
┌─────────────────────┴─────────────────────┐
|
||||
▼ ▼
|
||||
KeypointFrame(239B) ──▶ WebSocket ──▶ Windows 骨架叠加层
|
||||
```
|
||||
|
||||
## 依赖的契约(已冻结于 opendance-web,v0.1.0)
|
||||
```
|
||||
app/src/main/java/com/opendance/studio/
|
||||
├── model/ 239 字节帧编解码 + 33 点拓扑(契约核心)
|
||||
├── camera/ CameraX 采集
|
||||
├── pose/ MediaPipe 端侧推理
|
||||
├── net/ WebSocket 推流 + 局域网主机发现
|
||||
├── data/ 设置持久化
|
||||
└── ui/ 连接页 / 运行页 / 关于页
|
||||
```
|
||||
|
||||
- `contracts/websocket-keypoints.md` — **239 字节关键点帧**编码规则(本端为发送方)
|
||||
- 帧头 8 字节:`magic(u16)=0x4F44` + `version(u8)=1` + `flags(u8)` + `frame_id(u32)`
|
||||
- 33 点 × 7 字节:`x(i16) y(i16) z(i16) conf(u8)`,小端序,归一化系数 32767
|
||||
- 文本控制帧:`hello` / `welcome` / `config` / `stats` / `bye`
|
||||
- `contracts/skeleton-topology.md` — MediaPipe 33 点顺序与坐标语义(**顺序一旦冻结不得重排**)
|
||||
- `contracts/open-source-credits.md` — 关于页必须展示的开源声明(三端共用)
|
||||
## 依赖的契约(opendance-web v0.1.0 冻结)
|
||||
|
||||
契约地址:https://gitea.kasugano.cn/zijunchiang/opendance-web/src/branch/main/contracts
|
||||
- [`contracts/websocket-keypoints.md`](contracts/websocket-keypoints.md) — 239 字节关键点帧(本端为**发送方**)
|
||||
- [`contracts/skeleton-topology.md`](contracts/skeleton-topology.md) — MediaPipe 33 点索引与坐标语义
|
||||
- [`contracts/open-source-credits.md`](contracts/open-source-credits.md) — 关于页必须展示的开源声明
|
||||
|
||||
参考实现:`opendance-web/web-server/src/preprocess/keypoint-codec.ts` 中的
|
||||
`encodeBinaryFrame()` 即本端序列化器的权威参考。
|
||||
`contracts/` 是**只读快照**。任何跨端契约变更必须先回到
|
||||
[`opendance-web`](https://gitea.kasugano.cn/zijunchiang/opendance-web) 修改并提升版本。
|
||||
|
||||
**任何跨端契约变更必须先回到 `opendance-web` 修改 `contracts/` 并提升版本**,
|
||||
再在本仓库创建适配任务。
|
||||
## 跨端一致性:金标准字节向量测试
|
||||
|
||||
## 关键约束
|
||||
本仓库最重要的测试不是「函数跑通了」,而是**与另两端逐位一致**:
|
||||
|
||||
- 仅使用 MediaPipe 33 点拓扑,**不使用 SMPL**(规避非商用许可限制)
|
||||
- 本端不做评分与渲染:只负责采集、端侧推理、编码、推流
|
||||
- 视频帧不离开设备,仅发送 33 个关键点
|
||||
- 发布产物必须包含关于页开源声明
|
||||
`KeypointFrameTest.goldenVectorMatchesWebImplementation` 用 opendance-web 已通过验收的
|
||||
TypeScript 实现生成 239 字节金标准向量,断言 Kotlin 实现产出完全相同的字节。
|
||||
这条测试同时守护三端(TypeScript / GDScript / Kotlin),任何一端私自改字段布局都会立刻失败。
|
||||
|
||||
## 已知限制
|
||||
|
||||
1. Godot(Windows 端)的 `WebSocketPeer` 不暴露握手请求路径,因此**无法校验 path 是否为 `/pose`**,
|
||||
本端仍按契约连接到 `/pose`,互操作不受影响。
|
||||
2. **未在真实 Android 设备上安装运行**(本环境无设备也无模拟器)。
|
||||
已验证到:构建通过、签名有效、包信息正确、模型与 4 个 ABI 的 native 库均正确打包。
|
||||
3. 主机发现依赖手机与电脑处于同一 WiFi;路由器开启 AP 隔离时无法互访(见 README.txt FAQ)。
|
||||
4. release 包只含 arm64-v8a + armeabi-v7a。x86/x86_64 仅供模拟器,会占掉约 27 MB,
|
||||
对真机用户没有价值;debug 包保留全部 4 个 ABI 以便模拟器调试。
|
||||
|
||||
## 第三方开源声明
|
||||
|
||||
见 [`THIRD_PARTY.md`](THIRD_PARTY.md),或应用内「关于」页面。
|
||||
未使用 SMPL 模型及其衍生拓扑,统一采用 MediaPipe 33 点拓扑。
|
||||
|
||||
Reference in New Issue
Block a user