docs: 消除 Gitea 模棱两可 Unicode 告警(全角标点紧邻 ASCII 时改为半角)
依据 Gitea v1.27.3 modules/charset/escape_stream.go 的判定规则 (analyzeDetectResults:仅当左右相邻字符都不是非 ASCII 时才标记, 且 _common 表恒定生效),把说明文档中会被标记的全角标点 (,:;?!() 等)改为半角,并保证成对括号宽度一致。 中文语境中的全角标点(左右均为中文)保持原样,不动代码与契约语义。
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# opendance-android
|
||||
|
||||
OpenDance Studio **阶段三**:Android 辅助 App(Kotlin + CameraX + MediaPipe 端侧推理)。
|
||||
OpenDance Studio **阶段三**: Android 辅助 App(Kotlin + CameraX + MediaPipe 端侧推理)。
|
||||
|
||||
用手机摄像头做**端侧**姿态推理,把 33 个骨骼关键点通过 WebSocket 推给 Windows 客户端,
|
||||
由后者驱动 VRM 角色并 DTW 实时评分。
|
||||
@@ -9,17 +9,17 @@ OpenDance Studio **阶段三**:Android 辅助 App(Kotlin + CameraX + MediaPi
|
||||
|
||||
## 状态
|
||||
|
||||
**阶段三已完成**:T-AND-001 -> T-AND-009 全部落地。
|
||||
**阶段三已完成**: T-AND-001 -> T-AND-009 全部落地。
|
||||
|
||||
| 验收项 | 结果 |
|
||||
|--|--|
|
||||
| 单元测试 | OK **30 项全部通过**(JVM,无需设备) |
|
||||
| 单元测试 | OK **30 项全部通过**(JVM,无需设备) |
|
||||
| **跨端金标准** | OK Kotlin 序列化器与 Web 端 TypeScript 实现**逐位一致** |
|
||||
| `./gradlew assembleRelease` | OK 生成**已签名** APK(28.6 MB) |
|
||||
| 签名校验 | OK `apksigner` 退出码 0,v2 方案,CN=OpenDance Studio Dev |
|
||||
| 包信息 | OK `com.opendance.studio` v0.1.0,minSdk 29(Android 10+)/ targetSdk 34 |
|
||||
| 模型随包分发 | OK `assets/pose_landmarker_lite.task` 5.7 MB(Stored 未压缩) |
|
||||
| ABI 覆盖 | OK arm64-v8a + armeabi-v7a(debug 额外含 x86/x86_64) |
|
||||
| `./gradlew assembleRelease` | OK 生成**已签名** APK(28.6 MB) |
|
||||
| 签名校验 | OK `apksigner` 退出码 0, v2 方案,CN=OpenDance Studio Dev |
|
||||
| 包信息 | OK `com.opendance.studio` v0.1.0, minSdk 29(Android 10+)/ targetSdk 34 |
|
||||
| 模型随包分发 | OK `assets/pose_landmarker_lite.task` 5.7 MB(Stored 未压缩) |
|
||||
| ABI 覆盖 | OK arm64-v8a + armeabi-v7a(debug 额外含 x86/x86_64) |
|
||||
|
||||
## 快速开始
|
||||
|
||||
@@ -33,7 +33,7 @@ bash build/build-apk.sh all # 仅构建 debug + release
|
||||
bash build/package-release.sh # 打发布包
|
||||
```
|
||||
|
||||
详细使用说明见 [`README.txt`](README.txt),工程约束见 [`DSH.md`](DSH.md),
|
||||
详细使用说明见 [`README.txt`](README.txt),工程约束见 [`DSH.md`](DSH.md),
|
||||
第一次上手请看下文的「初次部署(从零跑起来)」一节。
|
||||
|
||||
## 初次部署(从零跑起来)
|
||||
@@ -46,14 +46,14 @@ bash build/package-release.sh # 打发布包
|
||||
|
||||
| 项 | 要求 | 依据 |
|
||||
|--|--|--|
|
||||
| JDK | 17 或更高(AGP 8.7.3 要求;`build/build-apk.sh` 会校验主版本 >= 17) | `gradle.properties` / `build/build-apk.sh` |
|
||||
| Gradle | 8.9,仓库自带 wrapper(`./gradlew`),本机无需另装 | `gradle/wrapper/gradle-wrapper.properties` |
|
||||
| Android SDK | `compileSdk 34` / `minSdk 29`(Android 10+)/ `targetSdk 34`;需 `platforms;android-34` 与 `build-tools;34.0.0` | `app/build.gradle.kts` |
|
||||
| 设备 | **需要真机**(Android 10 及以上、带摄像头);模拟器只作有限调试 | `app/build.gradle.kts` 的 ABI 过滤 |
|
||||
| JDK | 17 或更高(AGP 8.7.3 要求;`build/build-apk.sh` 会校验主版本 >= 17) | `gradle.properties` / `build/build-apk.sh` |
|
||||
| Gradle | 8.9,仓库自带 wrapper(`./gradlew`),本机无需另装 | `gradle/wrapper/gradle-wrapper.properties` |
|
||||
| Android SDK | `compileSdk 34` / `minSdk 29`(Android 10+)/ `targetSdk 34`;需 `platforms;android-34` 与 `build-tools;34.0.0` | `app/build.gradle.kts` |
|
||||
| 设备 | **需要真机**(Android 10 及以上、带摄像头);模拟器只作有限调试 | `app/build.gradle.kts` 的 ABI 过滤 |
|
||||
|
||||
真机与模拟器的差别:
|
||||
|
||||
- release 包只打包 `arm64-v8a` + `armeabi-v7a`,**无法安装到 x86/x86_64 模拟器**。
|
||||
- release 包只打包 `arm64-v8a` + `armeabi-v7a`, **无法安装到 x86/x86_64 模拟器**。
|
||||
- debug 包额外含 `x86`/`x86_64`,可以装进模拟器,但模拟器相机是虚拟场景,
|
||||
CameraX 取到的是合成画面,MediaPipe 的姿态识别效果不能代表真机,
|
||||
也不能作为「第一次跑通」的验收依据。
|
||||
@@ -79,7 +79,7 @@ sdk.dir=<Android SDK 路径>
|
||||
`build/build-apk.sh` 在该文件缺失时会依据 `ANDROID_HOME` / `ANDROID_SDK_ROOT`
|
||||
自动生成它;也可以手动创建。**不要提交它**,每台机器路径不同。
|
||||
|
||||
签名材料同样**不入库**(`.gitignore` 已忽略 `keystore/`、`*.jks`、`*.keystore`、
|
||||
签名材料同样**不入库**(`.gitignore` 已忽略 `keystore/`、`*.jks`、`*.keystore`、
|
||||
`keystore.properties`):
|
||||
|
||||
- 仓库里**没有私钥**,只有生成脚本与说明。
|
||||
@@ -88,7 +88,7 @@ sdk.dir=<Android SDK 路径>
|
||||
(含 `storeFile`、`keyAlias` 与两个口令字段)。**请自行备份,且不要提交**。
|
||||
- `app/build.gradle.kts` 的签名取值优先级:
|
||||
`keystore.properties` -> 环境变量(`KEYSTORE_PATH` / `KEYSTORE_PASSWORD` /
|
||||
`KEY_ALIAS` / `KEY_PASSWORD`)-> 回退 debug 签名。
|
||||
`KEY_ALIAS` / `KEY_PASSWORD`)-> 回退 debug 签名。
|
||||
回退只为让 CI 也能产出已签名 APK;正式发布必须提供自己的 keystore。
|
||||
|
||||
### 3. 首次构建
|
||||
@@ -140,9 +140,9 @@ adb install -r app/build/outputs/apk/release/app-release.apk
|
||||
|
||||
| 界面字段 | 设置项 | 默认值 | 说明 |
|
||||
|--|--|--|--|
|
||||
| IP 地址 | `host` | RFC 5737 文档网段占位地址(源码为 `192.0.2.100`,**非真实主机**) | 填 Windows 电脑的局域网 IP |
|
||||
| IP 地址 | `host` | RFC 5737 文档网段占位地址(源码为 `192.0.2.100`, **非真实主机**) | 填 Windows 电脑的局域网 IP |
|
||||
| 端口 | `port` | `8765` | 与 Windows 客户端监听端口一致 |
|
||||
| 目标帧率(FPS) | `targetFps` | `30` | 取值范围 5~60 |
|
||||
| 目标帧率(FPS) | `targetFps` | `30` | 取值范围 5~60 |
|
||||
| 分辨率 | `resolution` | `640x480` | 可选 `480x360` / `640x480` / `1280x720` |
|
||||
| 镜像画面 | `mirror` | 开 | 只影响显示与 `flags.bit0`,发送的是未镜像坐标 |
|
||||
| 仅上半身模式 | `upperBodyOnly` | 关 | 下半身置信度置 0,接收端插值 |
|
||||
@@ -183,10 +183,10 @@ IP 地址:192.0.2.10 # RFC 5737 文档示例网段,实际填你电脑
|
||||
| # | 命令 | 预期输出 |
|
||||
|--|--|--|
|
||||
| 1 | `./gradlew testDebugUnitTest` | `BUILD SUCCESSFUL`,全部用例通过;报告在 `app/build/reports/tests/testDebugUnitTest/index.html` |
|
||||
| 2 | `bash build/build-apk.sh debug` | 末尾打印 `OK Debug APK:app/build/outputs/apk/debug/app-debug.apk` 及其大小与签名信息 |
|
||||
| 3 | `bash build/build-apk.sh all` | debug 与 release 均 `OK`;release 显示 `已签名(APK Signature Scheme v2)` |
|
||||
| 2 | `bash build/build-apk.sh debug` | 末尾打印 `OK Debug APK: app/build/outputs/apk/debug/app-debug.apk` 及其大小与签名信息 |
|
||||
| 3 | `bash build/build-apk.sh all` | debug 与 release 均 `OK`; release 显示 `已签名(APK Signature Scheme v2)` |
|
||||
| 4 | `$ANDROID_HOME/build-tools/34.0.0/apksigner verify app/build/outputs/apk/release/app-release.apk` | 退出码 0(无输出即通过) |
|
||||
| 5 | `unzip -l app/build/outputs/apk/release/app-release.apk \| grep pose_landmarker_lite.task` | 列出 `assets/pose_landmarker_lite.task`(约 5.7 MB,Stored 未压缩) |
|
||||
| 5 | `unzip -l app/build/outputs/apk/release/app-release.apk \| grep pose_landmarker_lite.task` | 列出 `assets/pose_landmarker_lite.task`(约 5.7 MB, Stored 未压缩) |
|
||||
| 6 | `adb install -r app/build/outputs/apk/debug/app-debug.apk` | `Success` |
|
||||
|
||||
其中 `KeypointFrameTest.goldenVectorMatchesWebImplementation` 必须通过:
|
||||
@@ -211,7 +211,7 @@ IP 地址:192.0.2.10 # RFC 5737 文档示例网段,实际填你电脑
|
||||
| 相机 | CameraX 1.4.0 |
|
||||
| 推理 | MediaPipe Tasks Vision 0.10.35 |
|
||||
| 通信 | OkHttp 4.12.0 |
|
||||
| UI | Jetpack Compose(BOM 2024.10.01,Material3) |
|
||||
| UI | Jetpack Compose(BOM 2024.10.01, Material3) |
|
||||
|
||||
## 数据流
|
||||
|
||||
@@ -235,7 +235,7 @@ app/src/main/java/com/opendance/studio/
|
||||
|
||||
## 依赖的契约(opendance-web v0.1.0 冻结)
|
||||
|
||||
- [`contracts/websocket-keypoints.md`](contracts/websocket-keypoints.md) - 239 字节关键点帧(本端为**发送方**)
|
||||
- [`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) - 关于页必须展示的开源声明
|
||||
|
||||
@@ -244,7 +244,7 @@ app/src/main/java/com/opendance/studio/
|
||||
|
||||
## 跨端一致性:金标准字节向量测试
|
||||
|
||||
本仓库最重要的测试不是「函数跑通了」,而是**与另两端逐位一致**:
|
||||
本仓库最重要的测试不是「函数跑通了」,而是**与另两端逐位一致**:
|
||||
|
||||
`KeypointFrameTest.goldenVectorMatchesWebImplementation` 用 opendance-web 已通过验收的
|
||||
TypeScript 实现生成 239 字节金标准向量,断言 Kotlin 实现产出完全相同的字节。
|
||||
@@ -252,12 +252,12 @@ TypeScript 实现生成 239 字节金标准向量,断言 Kotlin 实现产出
|
||||
|
||||
## 已知限制
|
||||
|
||||
1. Godot(Windows 端)的 `WebSocketPeer` 不暴露握手请求路径,因此**无法校验 path 是否为 `/pose`**,
|
||||
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,
|
||||
4. release 包只含 arm64-v8a + armeabi-v7a。x86/x86_64 仅供模拟器,会占掉约 27 MB,
|
||||
对真机用户没有价值;debug 包保留全部 4 个 ABI 以便模拟器调试。
|
||||
|
||||
## 第三方开源声明
|
||||
|
||||
Reference in New Issue
Block a user