akirco/pigma

GitHub: akirco/pigma

一个基于 Ratatui 构建的终端 UI 音乐播放器,支持网易云音乐和本地音频的流式播放与管理。

Stars: 9 | Forks: 2

# pigma(开发中) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/akirco/pigma/actions/workflows/ci.yml) [![Release](https://static.pigsec.cn/wp-content/uploads/repos/cas/42/42ba98a60a0bb3b0ad908f024db145f9c5b831eb7df822f56ac578ee7d7215b3.svg)](https://github.com/akirco/pigma/actions/workflows/release.yml) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) 一个使用 [Ratatui](https://ratatui.rs) 构建的 NetEase Cloud Music (网易云音乐) 或本地音频播放 TUI 客户端。 **注意:** **升级注意备份配置文件,当前自动备份迁移并没有写** ## 功能 - [x] 流式播放,边听边存 - [x] 低延迟 seek - [x] 本地音频播放 - [x] 自定义渲染列表 - [x] 自定义渲染列 - [x] 歌词渐变逐字高亮 - [x] table 标题自定义 - [x] 最近播放上报 - [x] 心动模式 - [x] 数据分页加载(目前仅支持云盘) - [x] youtube 源 fallback(音源评分重写) - [ ] 音量控制 - [ ] landing page - [ ] 重构进入程序流程 - [ ] 歌曲操作(like、dislike、fav 等) - [ ] 重构播放队列 - [ ] 引入数据库,内存优化 - [ ] 本地音频歌词,元数据重写 - [ ] 下载管理(重合边听边存) - [ ] 云盘源作为 fallback - [ ] 云盘上传 - [ ] 歌手信息 - [ ] 更多 layout 支持 - [ ] 重写 playerbar(支持歌曲封面) - [ ] table 标题自定位置 - [ ] ascii art style 歌词 - [ ] 支持系统包管理器安装 ## 预览
## 安装 ### 从 releases 安装 ``` # https://github.com/marcosnils/bin bin install https://github.com/akirco/pigma ``` `windows(scoop)` ``` scoop bucket add aki 'https://github.com/akirco/aki-apps.git' scoop install aki/pigma ``` ### 从源码安装 (cargo) ``` cargo install --git https://github.com/akirco/pigma.git ``` ### 从源码编译 ``` git clone https://github.com/akirco/pigma.git cd pigma cargo build --release # 位于 target/release/pigma 的 binary ``` ## 用法 | 快捷键 | 描述 | | :------------------ | :--------------------------------------: | | tab/shift+tab | 切换导航 | | enter | 播放/进入列表 | | space | 暂停 | | f | 播放队列 | | l | 歌词 | | / | 搜索/过滤 | | b | 样式切换 | | left /right | seek 15s | | shift + left /right | 上一首/下一首 | | ctrl+p | command panel | | p | 切换表格为 cell/row 模式 | | m | 切换播放模式(心动模式存在问题,需重写) | ## 配置 配置文件位置:`~/.config/pigma/config.toml` ### 列配置 每种内容类型都有两个级别的列:**type-defaults** 和 **per-API overrides**。 下面两种写法在 TOML 中等价,**手写时均可使用**: **写法一:内联数组(紧凑)** ``` [columns] songs = [ { header = "TITLE", field = "name", min_width = 18 }, { header = "ARTIST", field = "singer", width = 16 }, { header = "ALBUM", field = "album", min_width = 12 }, { header = "DURATION", field = "duration", width = 9 }, ] songlist = [ { header = "NAME", field = "name", min_width = 20 }, { header = "AUTHOR", field = "author", width = 16 }, ] [columns.overrides] toplist = [ { header = "NAME", field = "name", width = 20 }, { header = "DESCRIPTION", field = "description", min_width = 20 }, ] search = [ { header = "HOT SEARCH", field = "keyword", min_width = 1 }, ] ``` **写法二:数组-of-tables(程序保存时采用此格式)** ``` [[columns.songs]] header = "TITLE" field = "name" min_width = 18 [[columns.songs]] header = "ARTIST" field = "singer" width = 16 [[columns.songs]] header = "ALBUM" field = "album" min_width = 12 [[columns.songs]] header = "DURATION" field = "duration" width = 9 [[columns.songlist]] header = "NAME" field = "name" min_width = 20 [[columns.songlist]] header = "AUTHOR" field = "author" width = 16 [[columns.overrides.toplist]] header = "NAME" field = "name" width = 20 [[columns.overrides.toplist]] header = "DESCRIPTION" field = "description" min_width = 20 [[columns.overrides.search]] header = "HOT SEARCH" field = "keyword" min_width = 1 ``` 两种写法均可被程序正确读取;`save()` 时统一以「写法二」写回磁盘。 #### 列宽类型 | 格式 | 描述 | | ---------------- | ----------------------- | | `width = 16` | 固定宽度(以字符计) | | `min_width = 18` | 最小宽度,自动弹性伸展 | | `ratio = [1, 3]` | 比例权重 | #### 各内容类型的可用字段 **`songs`** (SongInfo) — 被以下 API 使用: | API | 描述 | | ----------------- | ---------------------- | | `recommend_songs` | 每日推荐 | | `user_cloud_disk` | 我的音乐云盘 | | `recent_songs` | 最近播放 | | `liked_songs` | 我喜欢的音乐 | | `local_music` | 本地音乐 | | Playlist entry | 歌单/排行榜内的歌曲 | 字段: | field | Type | 备注 | | ---------- | ------ | --------------------------------- | | `name` | String | 歌曲名 | | `singer` | String | 歌手 | | `album` | String | 专辑 | | `duration` | String | 时长,已格式化为 `MM:SS`(自动) | **`songlist`** (SongList) — 被以下 API 使用: | API | 描述 | | -------------------- | -------- | | `recommend_resource` | 推荐歌单 | | `top_song_list` | 歌单 | | `user_radio_sublist` | 电台 | | `user_song_list` | 我的歌单 | 字段: | field | Type | 备注 | | -------- | ------ | ------ | | `name` | String | 歌单名 | | `author` | String | 作者 | **`toplist` (override)** (TopList): | API | 描述 | | --------- | -------- | | `toplist` | 排行榜 | 字段: | field | Type | 备注 | | ------------- | ------ | ------ | | `name` | String | 榜单名 | | `description` | String | 描述 | **`singers`** (SingerInfo) — 被以下 API 使用: | API | 描述 | | ------------- | -------- | | `top_singers` | 热门歌手 | 字段: | field | Type | 备注 | | ------ | ------ | ------- | | `name` | String | 歌手名 | | `id` | u64 | 歌手 ID | **`search` (override)** (HotSearch): | API | 描述 | | -------- | ---------- | | `search` | 搜索-热搜榜 | 字段: | field | Type | 备注 | | --------- | ------ | --------- | | `keyword` | String | 搜索关键词 | #### 所有 override 键 任何 API endpoint 都可以有一个 `[columns.overrides.{key}]` 条目。可用的键: | Key | Default type | 描述 | | -------------------- | ------------ | ---------------- | | `recommend_songs` | songs | 每日推荐 | | `recommend_resource` | songlist | 推荐歌单 | | `toplist` | toplist | 排行榜 | | `top_song_list` | songlist | 歌单 | | `user_radio_sublist` | songlist | 电台 | | `user_cloud_disk` | songs | 我的音乐云盘 | | `__liked__` | songs | 我喜欢的音乐 | | `user_song_list` | songlist | 我的歌单 | | `__local_music__` | songs | 本地音乐 | | `__recent__` | songs | 最近播放 | | `top_singers` | singers | 热门歌手 | | `search` | songs | 搜索-热搜榜 | | `__download__` | — | 下载管理(未实现) | ### 标题模板 ``` [titles] sidebar = "NAVIGATION" playlist = "\u266a QUEUE ({count})" # {count} = song count lyrics = "\u266a LYRICS" ``` NavItem 标题模板支持 `{name}` 和 `{count}` 占位符。 ### 进度条自定义 ``` [playerbar] filled_symbol = "━" unfilled_symbol = "─" filled_color = "accent" # theme field name for progress unfilled_color = "muted" # theme field name for track (uncached) unfilled_color_cached = "highlight" # theme field name for track (cached) ``` 支持的 theme 颜色名称:`bg`、`surface`、`text`、`accent`、`highlight`、`muted`、`error`、`warning`。 ### 内容缓存 ``` content_cache_ttl = 300 # seconds, 0 to disable ``` ### 歌词渐变 歌词当前行高亮渐变风格(自实现,无额外依赖): ``` lyric_gradient = "warm" # warm | cubehelix | rainbow | spectral | viridis | turbo ``` 未知值回退到 `warm`。 ### 导航项 每个 nav item 可以包含: ``` [[navigation.sections.items]] name = "推荐歌单" api = "recommend_resource" title_template = "{name} ({count})" ``` #### 标题区块支持富文本标记 `[[navigation.sections]]` 条目的 `title` 支持由活动 theme 设置样式的内联标记标签: | Tag | 含义 | | -------------------- | ---------- | | `` | 强调色 | | `` | 加粗 | 示例(默认值): ``` [[navigation.sections]] title = " DISCOVER" [[navigation.sections.items]] name = "每日推荐" # 同样支持title的标记语法 api = "recommend_songs" title_template = "{name} ({count})" ``` ### Theme pigma 不再附带内置 theme。你必须在配置中定义一个或多个 `[[themes]]` 条目,并通过 `default_theme`(根据 `name` 匹配)选择要激活的 theme。如果 `themes` 为空,UI 将回退到内置的默认调色板。 ``` default_theme = "rose-pine" [[themes]] name = "rose-pine" bg = "#191724" surface = "#26233A" text = "#E0DEF4" accent = "#EB6F92" highlight = "#31748F" muted = "#6E6A86" error = "#EB6F92" warning = "#F6C177" ``` 支持的 theme 颜色字段:`bg`、`surface`、`text`、`accent`、`highlight`、`muted`、`error`、`warning`。 你可以定义多个 theme,并在运行时切换它们(样式切换,默认按键 `b`)。 ## 开发 ``` git clone https://github.com/akirco/pigma.git cd pigma cargo run ``` ## License 基于 [Apach-2.0](LICENSE) license 授权。
标签:Python安全, Ratatui, Rust, TUI, 可视化界面, 本地音频, 流媒体, 网易云音乐, 网络流量审计, 通知系统, 音乐播放器