Skip to content

Commit 17ae83d

Browse files
committed
feat(kss): enhance scripting system with pagination, crypto support, and improved playback robustness
- KSS Enhancements: - Implement paginated discovery (home list) with `LoadMoreHome` support in UI and ViewModel. - Add `CryptoBridge` to the scripting engine for MD5 and AES cryptographic operations. - Improve `HostBridge` with default User-Agent, custom headers, and hex/binary response support. - Refactor music sources to return `MusicListResult` containing total counts for better list management. - Playback & UX: - Implement automatic background playlist hydration when starting playback from a script-based source. - Add automatic retry for 403 Forbidden errors and 20-minute expiration for resolved URL caches in `KanadePlaybackService`. - Improve `OkHttpClient` configuration in `ScriptManager` with optimized timeouts and connection pooling. - Documentation & Polish: - Add a comprehensive Chinese `README.md` with architecture and quick-start guides. - Update `GEMINI.md` and `SCRIPTS.md` to align with the latest architecture and "Chief Scientist" protocols. - Update `KSS_DEVELOPER_GUIDE.md` to reflect v1.1 API changes (native config objects, new bridge methods).
1 parent df1430c commit 17ae83d

21 files changed

Lines changed: 641 additions & 328 deletions

GEMINI.md

Lines changed: 66 additions & 126 deletions
Large diffs are not rendered by default.

KSS_DEVELOPER_GUIDE.md

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ A KSS script is a single `.js` file consisting of two parts:
2222
* "description": "Fetches music from my private API",
2323
* "configs": [
2424
* { "key": "api_key", "label": "API Key", "type": "string", "default": "" },
25-
* { "key": "high_quality", "label": "HQ Audio", "type": "boolean", "default": "false" }
25+
* { "key": "quality", "label": "Audio Quality", "type": "select", "default": "128k", "options": ["128k", "320k", "flac"] }
2626
* ]
2727
* }
2828
*/
@@ -39,24 +39,25 @@ A KSS script is a single `.js` file consisting of two parts:
3939
| `version` | `string` | Semantic versioning (e.g., `1.2.3`). |
4040
| `author` | `string` | Your name or handle. |
4141
| `description` | `string?` | Optional short description. |
42-
| `configs` | `array?` | List of user-configurable variables (see below). |
42+
| `configs` | `array?` | List of user-configurable variables. |
4343

4444
### Configuration Items (`configs`)
4545
- `key`: The internal key used in code.
4646
- `label`: Display name in the Settings UI.
47-
- `type`: One of `"string"`, `"number"`, or `"boolean"`.
47+
- `type`: One of `"string"`, `"number"`, `"boolean"`, or `"select"`.
4848
- `default`: Default value (as a string).
49+
- `options`: (For `select` type) List of possible string values.
4950

5051
---
5152

5253
## 3. Core Interface
5354

5455
You must implement the following functions. They can be standard functions or `async` functions.
5556

56-
### `init(configJson)`
57+
### `init(config)`
5758
Called once when the engine starts or when settings change.
58-
- `configJson`: A JSON string containing current user settings.
59-
- **Tip**: Always `JSON.parse(configJson)` at the start.
59+
- `config`: A JavaScript object containing current user settings.
60+
- **Note**: Values are provided based on the `type` defined in the manifest.
6061

6162
### `getHomeList()`
6263
Called to populate the "Discover" section on the Library screen.
@@ -77,6 +78,10 @@ Called when a track is about to be played.
7778
Called to fetch lyrics for a specific track.
7879
- **Returns**: A raw string (`LRC` or `TTML` format).
7980

81+
### `getMusicListByIds(ids)` (Optional)
82+
Batch fetch music details for a list of IDs.
83+
- **Returns**: `MusicItem[]`
84+
8085
---
8186

8287
## 4. Data Models
@@ -86,7 +91,7 @@ Called to fetch lyrics for a specific track.
8691
{
8792
id: "track_123", // String
8893
title: "Song Title", // String
89-
artist: "Artist Name",// String (comma separated for multiple)
94+
artist: "Artist A, B",// String (comma separated for multiple)
9095
album: "Album Name", // String (optional)
9196
cover: "https://...", // String (URL, optional)
9297
duration: 180 // Number (Seconds, optional)
@@ -111,39 +116,36 @@ Called to fetch lyrics for a specific track.
111116

112117
The following global objects are provided by the Kanade host:
113118

114-
### `console.log(message)`
115-
Prints a message to the Android Logcat (Tag: `KanadeScript`).
119+
### `console`
120+
- `console.log/info/debug/warn/error(...args)`: Standard logging.
116121

117-
### `http.get(url, options)`
118-
Performs a synchronous network request.
119-
- **Returns**: Response body as a string.
122+
### `http`
123+
- `http.get(url, options)`: Performs a network request.
124+
- `http.post(url, body, options)`: Performs an HTTP POST request.
120125

121-
### `http.post(url, body, options)`
122-
Performs an HTTP POST request.
123-
- **Returns**: Response body as a string.
124-
125-
---
126+
**Options**:
127+
- `headers`: `{ "Key": "Value" }`
128+
- `responseType`: `"text"` or `"hex"` (for binary data).
129+
- `contentType`: (POST only) e.g., `"application/json"`.
126130

127-
## 6. Deployment & Testing
128-
129-
1. Open **Settings** -> **Script Management** in Kanade.
130-
2. Click the **"+" (Import Script)** button.
131-
3. Select your `.js` file.
132-
4. Toggle the **Switch** to activate your script.
133-
5. If your script has configurations, click the **Gear** icon to edit them.
134-
6. Check the **Library** or **Search** screen to see your data.
131+
### `crypto`
132+
- `crypto.md5(text)`: Returns MD5 hex string.
133+
- `crypto.aesEncrypt(text, key, mode, padding)`: AES encryption.
134+
- `crypto.aesDecrypt(hex, key, mode, padding)`: AES decryption.
135+
- *Modes*: `"CBC"`, `"ECB"`, etc.
136+
- *Padding*: `"PKCS5Padding"`, `"NoPadding"`, etc.
135137

136138
---
137139

138-
## 7. Full Boilerplate
140+
## 6. Full Boilerplate
139141

140142
```javascript
141143
/**
142144
* @kanade_script
143145
* {
144146
* "id": "boilerplate",
145147
* "name": "Boilerplate Provider",
146-
* "version": "1.0.0",
148+
* "version": "1.1.0",
147149
* "author": "Kanade",
148150
* "configs": [
149151
* { "key": "user", "label": "Username", "type": "string", "default": "Guest" }
@@ -154,7 +156,7 @@ Performs an HTTP POST request.
154156
let settings = {};
155157

156158
function init(config) {
157-
settings = JSON.parse(config);
159+
settings = config;
158160
}
159161

160162
function getHomeList() {
@@ -163,8 +165,8 @@ function getHomeList() {
163165
];
164166
}
165167

166-
function search(query, page) {
167-
// const results = http.get("https://api.example.com/search?q=" + query);
168+
async function search(query, page) {
169+
// const results = await http.get("https://api.example.com/search?q=" + query);
168170
// return JSON.parse(results).items;
169171
return [];
170172
}
@@ -175,4 +177,4 @@ function getMediaUrl(id) {
175177
format: "mp3"
176178
};
177179
}
178-
```
180+
```

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Kanade (奏) - 高性能 Android 音乐播放器
2+
3+
**Kanade** 是一款专注于极致播放体验、现代 UI 设计与高度可扩展性的 Android 音乐播放器。它基于 Clean Architecture 与 MVI 架构开发,结合了强大的本地播放能力与创新的脚本系统 (KSS),旨在为用户提供纯粹且强大的音乐享受。
4+
5+
---
6+
7+
## ✨ 核心特性
8+
9+
- **🎶 卓越的播放引擎**:基于 **Android Media3 (ExoPlayer)**,支持无缝切换、背景播放以及系统级媒体控制中心集成。
10+
- **📜 极致歌词体验**
11+
- 支持标准 LRC、增强型 LRC 及 TTML (Apple Style) 格式。
12+
- **逐字同步**:支持 Karaoke 风格的横向平滑填充效果。
13+
- **系统联动**:通过 `Lyric-Getter-API``SuperLyricApi` 将歌词实时共享至系统状态栏或桌面悬浮窗。
14+
- **🚀 Kanade Scripting System (KSS)**
15+
- 内置 **QuickJS** 引擎,支持通过 JavaScript 编写外部音源插件。
16+
- **🎨 现代沉浸式 UI**
17+
- 全面采用 **Jetpack Compose****Material 3** 设计规范。
18+
- **动态色彩**:基于专辑封面自动提取主题色 (Palette),生成流光背景。
19+
- **灵动过渡**:播放器容器支持手势跟随,MiniPlayer 与全屏模式之间通过线性插值 (lerp) 实现丝滑形变。
20+
- **🔍 智能库管理**
21+
- 快速扫描本地媒体库,支持按艺术家、专辑、文件夹分类。
22+
- **智能艺术家识别**:自动计算合辑 (Compilations) 中的 "Various Artists",优化乱序的元数据展示。
23+
- **🌍 多语言支持**:原生支持简体中文、繁体中文及英文。
24+
25+
---
26+
27+
## 🛠️ 技术栈
28+
29+
| 模块 | 技术选型 |
30+
| :--- | :--- |
31+
| **编程语言** | Kotlin (JVM 17), JavaScript (QuickJS) |
32+
| **界面框架** | Jetpack Compose (Material 3) |
33+
| **音频引擎** | Android Media3 (ExoPlayer + MediaSession) |
34+
| **架构模式** | Clean Architecture + MVI (Model-View-Intent) |
35+
| **脚本引擎** | app.cash.quickjs:quickjs-android |
36+
| **图像加载** | Coil + Palette (颜色提取) |
37+
| **数据持久化** | Jetpack DataStore |
38+
| **网络层** | OkHttp 4 |
39+
40+
---
41+
42+
## 📦 项目结构
43+
44+
```text
45+
app/src/main/java/org/parallel_sekai/kanade/
46+
├── data/
47+
│ ├── parser/ # 歌词解析器 (LRC/TTML)
48+
│ ├── repository/ # 数据仓库 (播放控制、设置、脚本管理)
49+
│ ├── script/ # KSS 核心实现 (QuickJS 桥接、指令分发)
50+
│ └── source/ # 音源实现 (本地 MediaStore / 脚本音源)
51+
├── service/ # KanadePlaybackService (Media3 后台服务)
52+
└── ui/
53+
├── screens/ # Compose 页面 (播放器、搜索、音乐库、设置)
54+
└── theme/ # Material 3 主题与原子化设计变量
55+
```
56+
57+
---
58+
59+
## 🚀 快速开始
60+
61+
### 编译要求
62+
- Android Studio Ladybug 或更高版本
63+
- JDK 17
64+
- Android SDK 26+ (建议在 API 36/Android 16 环境下运行)
65+
66+
### 构建步骤
67+
1. 克隆仓库:
68+
```bash
69+
git clone https://github.com/your-username/kanade.git
70+
```
71+
2. 使用 Gradle 编译:
72+
```bash
73+
./gradlew assembleDebug
74+
```
75+
76+
---
77+
78+
## 📜 脚本系统 (KSS)
79+
80+
Kanade 的核心竞争力在于其插件化。你可以通过编写简单的 JavaScript 脚本来扩展音源。
81+
82+
- **脚本位置**:导入的脚本存储在应用私有目录,默认内置 `mock_provider.js`
83+
- **能力**:脚本可以访问网络 (HTTP GET/POST)、加密库 (MD5/AES) 以及日志系统。
84+
- **延迟加载**:采用 `ResolvingDataSource` 技术,仅在即将播放时解析脚本 URL,极大节省流量与内存。
85+
86+
详情请参考 [KSS 开发者指南](./KSS_DEVELOPER_GUIDE.md)
87+
88+
---
89+
90+
## 🤝 贡献与反馈
91+
92+
我们欢迎任何形式的 Contribution!
93+
- 如果你发现了 Bug,请提交 [Issue](https://github.com/your-username/kanade/issues)
94+
- 如果你有新的脚本或功能想法,欢迎提交 Pull Request。
95+
96+
---
97+
98+
## 📄 开源协议
99+
本项目采用 [Apache License 2.0](LICENSE) 协议开源。

0 commit comments

Comments
 (0)