Files
maidong-ktv/README.md
T
zijunchiang d01269e917 取址改为官方源优先+自建源兜底,只有官方源成功才上报(V1.6.2/45,未发布)
需求一:流程反转 + 上报绑定官方源成功
- 默认 sourceHosts 反转为 ["http://zk.ktv1.top:6677", "https://mdmuse.kasugano.cn"];
  SourceHosts.DEFAULT / SongUrlResolver.DEFAULT_HOSTS(收敛为引用前者)/ ktv_api.js
  CONFIG.HOSTS+HOST 三处一致。
- 取址结果改为 SourcedSongUrl(url, sourceHost)(**显式来源标志**,不靠 URL 猜):
  新增 SongSourceFlow(回落链 firstAvailable / 上报判定 shouldReportToSelfHost /
  全失败信号);JS 侧新增 android.onSongSource(requestId, host) 回传命中的源。
- 汇合点 SongApiClient.getSongDownloadUrl 只在"地址来自官方源"时才 POST /push_download;
  自建源自己给的地址与 DB 回落都不上报。
- 推送默认目标改为"从歌曲源列表里找第一个自建源"(自建源不再排第一,旧写法会直接关掉推送)。
- 1.6.1 落盘的旧默认顺序(自建源优先)在 KtvStore.load() 里一次性迁移;自定义列表不动。
- 业务码 404(自建源没有这首歌)仍只当"该源没地址",不置 sawForbidden、不进冷却、不污染受限统计。

需求二:6 条隐患
1) 设置页改源对 JS 立即生效:KtvJsBridge.applySourceSettingsNow 重新注入 KtvApiConfig.*
   并把已构造实例的 window.api.sourceOrder 重置为新列表;SongApiClient.applySourceSettings 接线。
2) JS 路径识别业务码 403:新增 KtvJsBridge.riskForbidden(status, body)(纯函数,手写判定
   避免 org.json 在单测里是空壳),HTTP 403 与 HTTP 200+{"code":403} 都算风控,与原生 sawForbidden 同口径。
3) isTrustedDownloadUrl 移除广告域名 ac16.vip 白名单,并改为黑名单优先(不再依赖调用顺序)。
4) MainActivity.download(song)(第五条地址消费点)补 AdVideoFilter.isTrustedSongUrl 闸门,
   不可信按"源失效"处理(Eac19WindowGuard.noteAllSourcesFailed),不再静默下载。
5) SongApiClient.fetchFromDb 不再静默吞异常:曲库打不开/查询异常各记一条 MiliLog.localWarn(含编号与异常)。
6) 删除死代码 streamDownloadAndPlay(全仓 grep 无调用点,且内部取址不过最终闸门)。

需求三:死代码/漂移清理(均先全仓搜索确认无引用)
- AdVideoFilter.replacementUrl 无任何写入点(恒为 null)→ 删除,resolve() 只保留"屏蔽"语义。
- ktv_api.js CONFIG.VER/VN 由"从不生效的死值"改为实际使用值 2.0 / 4.1.3.03281430。
- CONFIG.HOST 改为被 getToken 真正读取(不再"注入但从未被读")。
- KTV_BRIDGE_API 14 → 15(JS 两处 + KtvJsBridge 两处校验);AGENTS.md / README.md / README.en.md
  的陈旧标记统一到 15。
- do.php 的 limit 与 i.php 的 retry/ordertype/end_date/heart_time 确认无消费方 → 不新增解析(保持现状)。

需求四:测试与打包
- 新增 SourceOrderConsistencyTest / SongSourceFlowTest / JsBridgeGateTest / DownloadEntryGateTest,
  更新 SourceHostsTest / AdVideoFilterTest;app/build.gradle 打开 unitTests.returnDefaultValues。
- testReleaseUnitTest --rerun-tasks --offline:12 个测试类 / 87 例全过。
- assembleRelease --offline 通过(lintVital NewApi 0 条);版本 1.6.1/44 → 1.6.2/45。

不发布:未推 Gitea/Gitee、未动 Release/tag。
2026-10-14 03:45:07 +08:00

160 lines
7.5 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.
<p align="center">
<img src="app/src/main/res/drawable-nodpi/ktv_logo.png" width="140" alt="麦动 KTV Logo">
</p>
<h1 align="center">麦动 KTV</h1>
<p align="center">面向 Android TV 与横屏点歌设备的本地 KTV 应用</p>
<p align="center">遥控器操作 · 歌曲检索 · 点播队列 · 下载管理 · 稳定播放</p>
## 📌 项目说明
> **本仓库**:[https://gitea.kasugano.cn/zijunchiang/maidong-ktv](https://gitea.kasugano.cn/zijunchiang/maidong-ktv)
>
> **内容框架来源**:[https://gitee.com/yangyachao-X/maidong-ktv](https://gitee.com/yangyachao-X/maidong-ktv)
>
> 本仓库基于上游「麦动 KTV」的界面与功能框架进行改造,并使用 **DSH(DeepSeek Harness)** 重写内核与数据源:重新实现曲库同步、歌曲源接入、设备认证、风控应对、远程日志与广告屏蔽等底层逻辑。上游框架的版权归原作者所有,本项目仅作学习与技术交流。
## ⚠️ 严正声明
本软件是**完全免费且公开源码**的个人学习与技术交流项目。
- **【禁止任何形式的营利性使用】**:本软件(包括源码和编译后的 APK)严禁任何商家或个人进行打包售卖、硬件预装、收费技术支持或商业运营。
- **【侵权必究】**:如果您是付费购买的本软件,说明您已被骗,请立即向平台举报商家并退款。
- 完整授权条款请参见项目根目录下的 [LICENSE](./LICENSE) 文件。
## 核心功能
- TV 遥控器全局导航,支持方向键、确认键、返回键和长按操作。
- 统一焦点反馈,按钮、列表、卡片、开关和弹窗均提供清晰的选中状态。
- 首页提供排行榜、歌名、歌星、常唱、收藏、分类和本地歌曲入口。
- 支持全网与本地歌曲检索、语种筛选、分页浏览和首字母键盘输入。
- 歌星页面支持头像标签分类和歌手歌曲浏览。
- 支持歌曲点播、批量点歌、置顶、收藏、取消收藏和文件管理。
- 已点、已唱和下载列表实时同步歌曲状态。
- 已下载歌曲直接加入队列;未下载歌曲完成下载后自动加入,不打断当前播放。
- 已点列表存在歌曲时自动开始播放,并在切歌后同步队列与播放状态。
- 手机扫码点歌(局域网 HTTP 服务 + 二维码)。
## 播放功能
- 使用 IJK 播放器处理本地与下载歌曲(双 ABI:arm64-v8a / armeabi-v7a)。
- 支持小窗播放与全屏播放,切换页面和执行点歌操作时保持视频连续播放。
- 支持播放、暂停、切歌、重唱、进度显示和拖动。
- 支持原唱与伴唱切换,并保持当前播放或暂停状态。
- 支持歌曲片头信息、播放提示和暂停常驻提示。
- 支持视频比例、自动全屏和音画同步设置。
## 内核与数据源(DSH 重写部分)
- **曲库**:统一走**官方 Muse 同步**(`mconn.cherryonline.cn` `mls-api/v1/sqlite/sync`,RSA 登录 + 增量文件校验),不再依赖代码托管仓库承载数据库。
- **歌曲源**:接入 `w.w345.my`(`i.php` 取 token → `do.php` 解析播放地址),固定设备标识并复刻签名算法;广告/错号资源(如返回 `wb66.cn/.../719.ts` 或文件名与 musicno 不一致)会被拦截并重试。
- **风控应对**:源对陌生出口 IP 存在试用窗口(约 10 分钟,403"检测到异常行为"),App 检测到 403 后弹窗提示更换公网 IP;同 token 退避重试,不放大请求量。
- **JS 热更新**:歌曲接口逻辑在 `app/src/main/assets/mobile/ktv_api.js`,安装后从本仓库自动拉取兼容版本(须保留 `KTV_BRIDGE_API: 15` 标记)。
- **应用更新**:以 Gitea Release 标签作为版本号(如 `1.3.0`),Release 需附带一个 `.apk` 附件;仅当标签高于当前 `BuildConfig.VERSION_NAME` 时提示下载。
## 🔧 编译教程
### 1. 环境要求
| 项目 | 要求 |
|---|---|
| JDK | OpenJDK **17** |
| Android SDK | `compileSdk 35`、`minSdk 21`、`targetSdk 25` |
| Gradle | 使用仓库自带 wrapper(**8.13**),无需单独安装 |
| 构建系统 | Linux / macOS / Windows(命令行) |
### 2. 准备 Android SDK
安装 `platforms;android-35`、`build-tools`(≥ 34)与平台工具,并接受许可:
```bash
export ANDROID_HOME=/path/to/android-sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
yes | sdkmanager --licenses > /dev/null
sdkmanager "platforms;android-35" "build-tools;35.0.0" "platform-tools"
```
### 3. 配置签名密钥
`app/build.gradle` 的 release 签名默认读取仓库外相对路径的密钥:
```groovy
storeFile file("../../ktv_keystore.jks")
storePassword "123456"
keyAlias "ktv"
keyPassword "123456"
```
即密钥位于仓库根目录的上一级(`<项目根>/../ktv_keystore.jks`)。若没有该密钥,可用 keytool 生成并放到对应位置(或直接改 `app/build.gradle` 中的路径与口令):
```bash
keytool -genkeypair -v \
-keystore ../ktv_keystore.jks \
-alias ktv -keyalg RSA -keysize 2048 -validity 10000 \
-storepass 123456 -keypass 123456 \
-dname "CN=Maidong KTV, OU=Dev, O=Maidong, L=Beijing, ST=Beijing, C=CN"
```
> 若只想快速跑通、不关心签名,可把 `app/build.gradle` 的 `signingConfigs.release` 临时替换为 `signingConfigs.debug`。
### 4. 执行编译
```bash
# 仓库根目录
cd maidong-ktv
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 # 按本机实际 JDK 路径调整
export ANDROID_HOME=/path/to/android-sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
./gradlew assembleRelease
```
首次运行会自动下载 Gradle 8.13 与依赖,耗时取决于网络。构建成功后在:
```
app/build/outputs/apk/release/app-release.apk
```
产物为已签名的 release APK,包含 `armeabi-v7a` 与 `arm64-v8a` 双 ABI。
### 5. 安装到设备
```bash
adb install -r app/build/outputs/apk/release/app-release.apk
```
首次启动会自动初始化曲库(官方 Muse 同步,需联网);播放歌曲时由 `ktv_api.js` 实时解析 `w.w345.my` 播放地址并下载到本地。
### 6. 常见问题
- **曲库初始化失败**:检查设备网络能否访问 `mconn.cherryonline.cn`;已在设置页提供「重置数据库」。
- **点歌报 403 / 无播放地址**:多为歌曲源对当前公网 IP 的试用窗口到期,重启光猫/路由器更换公网 IP 后恢复。
- **热更新脚本不生效**:确认远端 `ktv_api.js` 保留 `KTV_BRIDGE_API: 15` 标记,否则内置版本优先。
- **想改签名/ABI**:编辑 `app/build.gradle` 的 `signingConfigs` 与 `ndk.abiFilters` 后重新编译。
## 项目结构
```
maidong-ktv/
├── app/
│ ├── src/main/java/com/local/ktv/ # Kotlin 源码
│ │ ├── MainActivity.kt # 主界面 / 播放 / 下载编排
│ │ ├── MuseDbSync.kt # 官方曲库同步
│ │ ├── MuseDatabase.kt # 曲库访问
│ │ ├── KtvJsBridge.kt # JS 桥(HTTP/RSA/热更新)
│ │ ├── MiliLog.kt # 远程日志上报(GlogCenter)
│ │ └── SongOkDownloadManager.kt # 下载管理
│ ├── src/main/assets/mobile/ktv_api.js # 歌曲源逻辑(热更新)
│ └── src/main/res/ # 资源 / 证书
├── tools/ # 辅助脚本
├── build.gradle / settings.gradle
└── gradlew
```
## 免责声明
本项目仅用于个人学习与技术交流。请遵守所在地区法律法规,尊重上游作者版权与歌曲版权;请勿将本软件用于任何商业或侵权用途。