Files
opendance-android/DSH.md
T
zijunchiang 264786134c docs: 新增「初次部署(从零跑起来)」;去混淆字符与真实内网信息
- README.md / README.txt 新增初次部署章节:前置条件(JDK 17 / SDK 34 / Gradle 8.9)、
  获取代码与本地配置(local.properties 不入仓)、Debug/Release 构建、装到手机与相机权限、
  连接配置(只连 Windows 客户端,默认 8765 / /pose)、第一次跑通、自检清单、常见问题
- 单测数量按实际(30 项)修正
- 三库同源契约:':=' 写法修回、去掉真实 MariaDB 版本串
- 全文去除易被 Gitea 判为「模棱两可 Unicode」的字符
- 本机 JDK 路径与内网示例地址改占位符 / RFC 5737 文档网段
2026-09-15 21:33:27 +08:00

139 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DSH.md -- opendance-android(OpenDance Studio 项目三:Android 辅助 App)
## 0. 本文件的作用
本文件是 **opendance-android 仓库内**的 DSH 执行约束。顶层说明书见
《DSH 开发文档:OpenDance Studio》,二者冲突时以顶层文档为准。
## 1. 项目定位
功能最单一的一端:用手机摄像头做端侧姿态推理,把 33 个骨骼关键点通过
WebSocket 推给 Windows 客户端。
```
手机摄像头 ──▶ MediaPipe Pose(端侧)──▶ 33 点关键点 ──▶ 239 字节帧
│
▼
ws://<windows-host>:8765/pose
```
**画面不离开设备** -- 只有关键点坐标经网络发送。
## 2. 技术栈
| 组件 | 选型 |
|--|--|
| 语言 | Kotlin 2.0.21 |
| 构建 | AGP 8.7.3 + Gradle 8.9 + JDK 17 |
| 相机 | CameraX 1.4.0 (Apache 2.0) |
| 推理 | MediaPipe Tasks Vision 0.10.35 (Apache 2.0) |
| 通信 | OkHttp 4.12.0 (Apache 2.0) |
| UI | Jetpack Compose(BOM 2024.10.01,Material3) |
## 3. 单次会话加载范围
允许加载:
1. 本文件 `DSH.md`
2. `project.yaml`
3. 当前 `tasks/xxx.md`
4. 该任务文件中 `load` 列出的文件
5. `contracts/` 中被明确引用的**锚点片段**
禁止加载:
- `opendance-web` / `opendance-windows` 的任何源码
- 非当前任务的 `tasks/*.md`
- 完整 `contracts/` 目录(只引用锚点)
- `.gradle/`、`app/build/`、`*.apk`、`keystore/`
## 4. 上下文预算
| 项 | 建议值 |
|--|--|
| 单任务文件数 | ≤ 6 |
| 单任务代码行数 | ≤ 1500 |
| 单任务 Token | ≤ 12K |
| 契约引用 | 只引用锚点,不加载全文 |
## 5. 目录结构
```
opendance-android/
├── settings.gradle.kts / build.gradle.kts / gradle.properties
├── gradlew / gradle/wrapper/ # Gradle 8.9 wrapper
├── project.yaml / DSH.md
├── tasks/ # 001~009 单任务说明书
├── contracts/ # 只读契约快照(来源 opendance-web v0.1.0)
├── app/
│ ├── build.gradle.kts # 依赖、签名、R8、ABI
│ ├── proguard-rules.pro # MediaPipe / OkHttp 的 keep 规则
│ └── src/
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/pose_landmarker_lite.task
│ │ └── java/com/opendance/studio/
│ │ ├── MainActivity.kt # 三页导航
│ │ ├── OpenDanceApp.kt # Application 单例容器
│ │ ├── model/ # 239 字节帧 + 33 点拓扑
│ │ ├── camera/ # CameraX
│ │ ├── pose/ # MediaPipe 推理
│ │ ├── net/ # WebSocket + 主机发现
│ │ ├── data/ # 设置
│ │ └── ui/ # 连接页 / 运行页 / 关于页
│ └── test/java/com/opendance/studio/ # JVM 单元测试
└── build/ # 打包与验证脚本
```
## 6. 硬性约束
1. **视频帧绝不离开设备**。只发送 33 个关键点坐标;这是本项目的隐私底线,
也是与「上传视频做云端推理」方案的本质区别。
2. **239 字节帧格式冻结**。任何字段改动都要先改 `opendance-web` 的
`contracts/websocket-keypoints.md` 并提升版本。
本端序列化器有金标准字节向量测试守护(见 8)。
3. **33 点顺序冻结**。MediaPipe Pose 的原始索引顺序**就是**契约顺序,
不得重排或插入。
4. **镜像语义**:发送**未镜像**的原始坐标,是否镜像由 `flags.bit0` 声明;
叠加层绘制时才按镜像显示。接收端据此决定如何还原。
5. **签名材料绝不入库**。`keystore/`、`keystore.properties`、`local.properties`
均已在 `.gitignore` 中。
6. 关于页与 `THIRD_PARTY.md` 必须与 `contracts/open-source-credits.md` 一致。
## 7. 验证(每任务执行)
```bash
export JAVA_HOME=<JDK 17 路径> # AGP 8.7 需要 JDK 17
export ANDROID_HOME=<Android SDK 路径>
./gradlew testDebugUnitTest # JVM 单元测试,无需设备
bash build/build-apk.sh all # debug + release APK,并校验签名与产物
bash build/verify.sh # 一键跑完上述全部并附加产物校验
```
首次部署(前置条件、本地配置、安装到手机、配置联通、自检清单、常见问题)
见 `README.md` 的「初次部署(从零跑起来)」与 `README.txt` 对应小节。
文档中的地址、路径、口令一律使用占位符,真实值不得写入仓库。
## 8. 跨端一致性验证(本项目最重要的测试)
`KeypointFrameTest.goldenVectorMatchesWebImplementation` 使用
**opendance-web 已通过验收的 TypeScript 实现**生成的 239 字节金标准向量,
断言 Kotlin 实现产出**逐位相同**的字节。
这条测试同时守护三端:TypeScript(服务端参考实现)、GDScript(Windows 端)、
Kotlin(本端)。任何一端私自改动字段布局都会立刻失败。
生成金标准向量的方法见 `tasks/004-keypoint-serializer.md`。
## 9. 上下文超标时的拆分策略
| 超标原因 | 拆分方式 |
|--|--|
| 单任务涉及多个界面 | 按界面拆(连接/运行/关于) |
| 单文件过大 | 按类拆,先生成接口再分实现 |
| 契约全文加载 | 改用锚点引用 |
| 需要参考其他项目 | 只读契约,不读源码 |
| UI 与逻辑耦合 | UI 只调用已定义接口(相机/推理/网络各自独立类) |
| 测试与实现同任务 | 测试单独任务,共享接口摘要 |