nemo1166/subsonic_client

0.1.1

Latest
uploaded 8 hours ago
Board-independent Subsonic / OpenSubsonic REST API client for ESP-IDF

Readme

# subsonic_client

面向 **乐鑫 ESP32 系列 SoC** 的 **板级无关** Subsonic / OpenSubsonic API 客户端组件(ESP-IDF)。

`subsonic_client` 只实现 **Subsonic 协议层**:REST 封装、认证、JSON 解析、元数据数据模型。
**不含** 音频解码/播放、UI、封面显示或任何开发板适配 —— 这些由使用方在应用层组合
(如配合 `esp_audio_simple_player` / `esp_player` 播放、`esp_lv_decoder` 显示封面)。

## 特性

- **认证**:token 认证(`t=md5(password+salt)` + `s=salt`,每次请求新 salt)、OpenSubsonic
  `apiKey` 认证(HTTP 基础认证之外)。
- **连通性**:`ping`
- **媒体库**:`getMusicFolders` / `getArtists` / `getArtist` / `getAlbum` / `getSong` /
  `getAlbumList2` / `getRandomSongs` / `search3`
- **流式播放**:`subsonic_build_stream_url()` 构建带认证参数的 `stream` URL(供播放引擎直接拉流)
- **封面 / 下载**:`getCoverArt` / `download` 流式落盘(自动识别并解析 JSON/XML 错误文档)
- **播放列表(只读)**:`getPlaylists` / `getPlaylist`
- **数据模型**:JSON → C 结构体(歌手 / 专辑 / 曲目 / 播放列表 / 错误码),列表内存
  PSRAM 优先分配,提供递归释放
- **错误处理**:本地错误走 `ESP_ERR_*`,服务端 `status=failed` 时用
  `subsonic_client_get_last_error()` 取回 Subsonic 错误码与消息

## 环境要求

- ESP-IDF `>= 5.3`
- 依赖:`esp_http_client` / `mbedtls`(IDF 内置)、`espressif/cjson`

## 安装

### 方式一:ESP Component Registry

```bash
idf.py add-dependency "<namespace>/subsonic_client"
```

### 方式二:本地路径(开发期)

在使用方工程 `CMakeLists.txt` 顶部:

```cmake
set(EXTRA_COMPONENT_DIRS ${CMAKE_SOURCE_DIR}/../esp-subsonic-client/components)
```

或在 `main/idf_component.yml`:

```yaml
dependencies:
  subsonic_client:
    path: ../../esp-subsonic-client/components/subsonic_client
```

## 配置(menuconfig → Subsonic Client)

| 配置项 | 默认 | 说明 |
| --- | --- | --- |
| `SUBSONIC_DEFAULT_API_VERSION` | `1.16.1` | 默认协议版本 |
| `SUBSONIC_HTTP_TIMEOUT_MS` | `5000` | 默认 HTTP 超时 |
| `SUBSONIC_MAX_RESPONSE_SIZE` | `65536` | JSON 响应缓冲上限(37 首专辑响应约 55KB) |
| `SUBSONIC_MAX_BINARY_SIZE` | `1048576` | 封面/文件下载大小上限 |
| `SUBSONIC_USE_PSRAM` | `y` | 有 PSRAM 时优先从外部 RAM 分配 |
| `SUBSONIC_ENABLE_PLAYLIST` | `y` | 播放列表端点开关 |
| `SUBSONIC_ENABLE_SCROBBLE` | `y` | 回写端点开关(当前为占位) |

## 最小使用

```c
#include "subsonic_client.h"

subsonic_client_config_t cfg = {
    .server = "http://192.168.1.10:4533",
    .username = "demo",
    .password = "secret",          /* 或 .api_key(二选一) */
    .client_name = "esp32p4_music",
    .api_version = "1.16.1",
    .timeout_ms = 5000,
};
subsonic_client_handle_t client = NULL;
subsonic_client_init(&cfg, &client);

if (subsonic_ping(client) != ESP_OK) { /* 登录失败 */ }

subsonic_album_list_t albums;
if (subsonic_get_album_list2(client, "newest", 20, 0, &albums) == ESP_OK) {
    /* albums.items[0].id / .name / .cover_art ... */
}
subsonic_album_list_free(&albums);

char url[512];
subsonic_build_stream_url(client, song_id, "mp3", 320, url, sizeof(url));

subsonic_client_deinit(client);
```

> 完整示例见本仓库 `examples/`(`minimal_ping` 最小连通性;`music_demo` 媒体库浏览)。
> 注意:所有返回的列表/字符串由组件分配,使用 `subsonic_*_free()` 释放。

## 测试

- 宿主单元测试(无需硬件):`pwsh -File tests/run_all.ps1 -SkipIntegration`
- 集成测试(需真实 Subsonic 服务器):见仓库 `tests/README.md`

## 错误码

| 返回 | 含义 |
| --- | --- |
| `ESP_OK` | 成功 |
| `ESP_FAIL` | 服务端 `status=failed`(用 `subsonic_client_get_last_error()` 取 Subsonic 错误码)或解析失败 |
| `ESP_ERR_NO_MEM` | 内存不足 / 响应超上限 |
| `ESP_ERR_TIMEOUT` | HTTP 超时 |
| `ESP_ERR_INVALID_ARG` | 参数非法 |
| `ESP_ERR_INVALID_STATE` | 未初始化 / 未设置错误 |

## 许可

MIT License(见仓库根 LICENSE)。依赖 `esp_http_client` / `cjson` / `mbedtls` 均为宽松许可。

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "nemo1166/subsonic_client^0.1.1"

download archive

Stats

  • Archive size
    Archive size ~ 19.21 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

nemo1166/subsonic_client version: 0.1.1
|