fin: 一个终端下的 Jellyfin 和 Subsonic 客户端
摘要
fin 是一个基于 Rust 的终端客户端,用于 Jellyfin 和 Subsonic 媒体服务器,提供带有进程内音频解码的 TUI,并支持 Chromecast 和 UPnP 播放。
<p><a href="https://lobste.rs/s/nwptul/fin_jellyfin_subsonic_client_for">评论</a></p>
查看缓存全文
缓存时间: 2026/07/06 12:04
# tsiry-sandratraina.com/fin 源代码:https://tangled.org/tsiry-sandratraina.com/fin README.md 发布(https://github.com/tsirysndr/fin/actions/workflows/release.yml)
> 一个面向终端的 Jellyfin 和 Subsonic 客户端 — 由 `symphonia`、`mpv`、Chromecast 和 UPnP 强力驱动
# fin — 赛博电光 Jellyfin/Subsonic TUI
`fin` 是一款 Rust 编写的 TUI(终端界面)+ 单次执行 CLI 工具。它能与你的 **Jellyfin** 或 **Subsonic** 服务器(Navidrome、Airsonic、Gonic、Astiga…… 登录时自动检测服务器类型)通信,搜索你的媒体库,管理播放列表,并将流推送到你的本地设备(**symphonia** 处理音频,**mpv** 处理视频)、你网络上的任意 **Chromecast** 设备,或任意 **UPnP MediaRenderer**(Sonos、Kodi、Roon 端点、三星/LG 电视、gmediarender 等)。本地播放现在完全原生处理音频 — HTTP 流式传输、解码、重采样和输出全部在进程内完成,音频永不经过 mpv。远程播放支持完整队列,客户端自动推进下一曲。
## 目录
- [功能特性](#features)
- [安装方式](#install)
- [macOS / Linux — Homebrew](#macos--linux--homebrew)
- [Debian / Ubuntu — `.deb`](#debian--ubuntu--deb)
- [Fedora / RHEL / openSUSE — `.rpm`](#fedora--rhel--opensuse--rpm)
- [Arch — 通过 AUR / 源代码](#arch--from-aur--source)
- [预编译压缩包](#prebuilt-tarballs)
- [从源代码构建](#from-source)
- [Nix](#nix)
- [快速开始](#getting-started)
- [渲染器选择](#renderer-selection)
- [所有设置项](#all-settings)
- [多服务器支持](#multiple-servers)
- [子命令](#sub-commands)
- [TUI 快捷键绑定](#keybindings-tui)
- [播放模式与效果](#playback-modes--effects)
- [随机播放](#shuffle)
- [重复播放](#repeat)
- [ReplayGain](#replaygain)
- [交叉渐变](#crossfade)
- [均衡器](#equalizer)
- [低音与高音](#bass--treble)
- [队列持久化](#queue-persistence)
- [远程渲染器队列](#remote-renderer-queue)
- [流媒体与转码](#streams--transcoding)
- [开发](#development)
- [许可证](#license)
## 功能特性
- **基于 Ratatui 的 TUI**,采用赛博电光色调(青色/青绿/紫色)。
- **进程内音频** — HTTP 流式传输 + `symphonia` 解码(MP3、FLAC、AAC、Opus、Vorbis、ALAC、WAV……)+ 重采样 + `cpal` 输出。mpv 仅用于视频。
- **fzf 风格即时搜索** — 每次按键结果即时更新。
- **逐层深入导航** — 在专辑上按 Enter 列出曲目,在剧集上按 Enter 列出分集,在播放列表上按 Enter 列出项目。按 `x` 一次性播放整个容器,按 `Shift+X` 则进行随机播放。
- **列表无限制** — 音乐、视频和播放列表会获取服务器上的所有项目,没有任何隐藏的任意数量限制。
- **三种渲染器,统一界面**:
- **本地**(默认)— 音频使用 symphonia + cpal,视频使用 mpv(仅在需要时启动)。
- **chromecast** — 通过 mDNS 发现设备,使用默认媒体接收器进行播放,带有**本地队列**,在 `FINISHED` 时自动推进。
- **upnp** — SSDP 发现任意 UPnP AV MediaRenderer,通过 AVTransport(`SetAVTransportURI`/`Play`/`Pause`/`Stop`/`Seek`)播放,通过 RenderingControl 控制音量。同样支持自动推进队列。
- **播放模式** — 随机播放、重复关闭/全部/单曲、[ReplayGain](#replaygain)(曲目/专辑)、相邻曲目之间的[交叉渐变](#crossfade)(传统余弦曲线*或*叠加 DJ 混音),以及由 Rockbox DSP 流水线驱动的 10 段[均衡器](#equalizer)。
- **队列持久化** — 音频队列、随机/重复状态以及当前曲目的精确播放位置都会在重启后保留。恢复时处于暂停状态;按 `Space` 即可从中断处继续播放。
- **真正的队列管理** — 加入队列、下一首播放、跳转曲目、移除单条、清空整个队列,并在专属标签页中查看队列,当前播放曲目标有 `▶` 标记。
- **播放列表** — 浏览、打开并播放你在服务器上保存的播放列表。
- **正在播放栏** — 显示标题、副标题、已播放/总时长、霓虹进度条、音量以及模式徽章(随机播放 ⇄、重复 ↻/↺、ReplayGain、交叉渐变 ⋈/≈)。
- **CLI 快捷方式**,便于脚本编写:`fin play "kind of blue"`、`fin queue --chromecast "Living Room" "wednesday"`、`fin play --upnp "Kitchen Speaker" "solaris"`、`fin devices`。
- **所有设置**都可以通过 **CLI 标志*或*TOML 键**访问 — 无论是一次性调用还是按机器配置,都能灵活使用。
- **纯 Rust TLS**(`rustls`) — 无需 OpenSSL。
## 安装方式
本地音频无需额外二进制文件 — 所有功能都内置于 `fin` 二进制文件中。**`mpv`** 仅在你实际播放本地视频时需要出现在 `$PATH` 中。以下每种安装路径要么自带 mpv,要么将其作为软依赖引入。
### macOS / Linux — Homebrew
```bash
brew install tsirysndr/tap/fin
```
该配方会自动拉入 `mpv`。
### Debian / Ubuntu — `.deb`
从[最新发布页](https://github.com/tsirysndr/fin/releases/latest)下载对应架构的 `.deb` 文件,然后:
```bash
# amd64
curl -LO https://github.com/tsirysndr/fin/releases/latest/download/fin_0.3.1_amd64.deb
sudo apt install ./fin_0.3.1_amd64.deb
# arm64(树莓派 4/5、Apple Silicon 虚拟机等)
curl -LO https://github.com/tsirysndr/fin/releases/latest/download/fin_0.3.1_arm64.deb
sudo apt install ./fin_0.3.1_arm64.deb
```
`apt` 会自动拉入 `libasound2`(cpal 的 ALSA 运行时)和 `mpv`。或者,一次性添加 Gemfury apt 源,之后正常使用 `apt install`:
```bash
echo "deb [trusted=yes] https://apt.fury.io/tsiry/ /" \
| sudo tee /etc/apt/sources.list.d/tsiry.list
sudo apt update && sudo apt install fin
```
### Fedora / RHEL / openSUSE — `.rpm`
```bash
sudo dnf install \
https://github.com/tsirysndr/fin/releases/latest/download/fin-0.3.1-1.x86_64.rpm
```
或通过 Gemfury yum 源:
```bash
sudo tee /etc/yum.repos.d/tsiry.repo <<'EOF'
[tsiry]
name=tsiry
baseurl=https://yum.fury.io/tsiry/
enabled=1
gpgcheck=0
EOF
sudo dnf install fin
```
### Arch — 通过 AUR / 源代码
先从官方仓库安装 `mpv`,然后:
```bash
sudo pacman -S mpv alsa-lib
cargo install --git https://github.com/tsirysndr/fin --bin fin
```
### 预编译压缩包
对于其他平台,请从[发布页](https://github.com/tsirysndr/fin/releases/latest)下载对应架构的压缩包:
- `fin-linux-amd64.tar.gz`
- `fin-linux-aarch64.tar.gz`
- `fin-macos-amd64.tar.gz`
- `fin-macos-aarch64.tar.gz`
每个压缩包都包含 `fin` 二进制文件 + 自述文件 + 许可证。请自行安装运行时依赖:
```bash
# macOS
brew install mpv # 仅视频需要;音频为进程内处理
# Debian / Ubuntu
sudo apt install libasound2 mpv
# Arch
sudo pacman -S alsa-lib mpv
```
### 从源代码构建
```bash
git clone https://github.com/tsirysndr/fin
cd fin
cargo install --path crates/fin
```
在 Linux 上构建需要 `libasound2-dev` + `pkg-config`(cpal 的 ALSA 后端);macOS 上 Core Audio SDK 已包含在工具链中。
### Nix
提供了 flake — mpv 已内置于包装中,无需额外安装步骤:
```bash
# 单次运行:
nix run github:tsirysndr/fin
# 安装到用户配置文件:
nix profile install github:tsirysndr/fin
# 开发环境(rust 工具链 + mpv + alsa-lib + clippy + rust-analyzer):
nix develop
```
## 快速开始
```bash
# 1. 登录
fin login https://media.example.com
# 2. 启动 TUI(默认子命令)
fin
# 3. 或者完全通过 shell 驱动
fin search "daft punk"
fin play "kind of blue"
fin queue "wednesday season 1"
fin devices # 列出局域网中的 Chromecast 和 UPnP 渲染器
fin play --chromecast "Living Room" "solaris"
fin play --upnp "Kitchen" "solaris"
```
## 渲染器选择
有三种方式选择渲染器 — 效果相同:
| 快捷标志 | 长标志 | 配置键 |
|----------|--------|--------|
| `--mpv` | `--renderer mpv` | `renderer = "mpv"` |
| `--chromecast "Living Room"` | `--renderer chromecast` | `renderer = "chromecast"` |
| `--upnp "Kitchen Speaker"` | `--renderer upnp` | `renderer = "upnp"` |
*(未指定 — 回退到本地)*
`--mpv` / `renderer = "mpv"` 标志名称是历史原因;它选择的是**本地**渲染器,音频使用 symphonia + cpal,视频使用 mpv。当你传递 `--chromecast NAME` 或 `--upnp NAME` 时,渲染器会自动切换到相应协议,并在连接时优先选择命名的设备。如果该名称未在网络中找到,fin 会选择第一个发现的设备。
## 所有设置项
每个设置既可作为 CLI 标志,也可作为 TOML 键使用。标志优先级更高。
| CLI 标志 | 环境变量 | TOML 键 | 默认值 |
|----------|----------|---------|--------|
| `--server URL` | `FIN_SERVER` | `servers[].url` | *(无)* |
| `--server-name NAME` | `FIN_SERVER_NAME` | `current_server` | *(最近登录的服务器)* |
| `--token TOKEN` | `FIN_TOKEN` | `servers[].access_token` | *(来自登录)* |
| `--user-id ID` | `FIN_USER_ID` | `servers[].user_id` | *(来自登录)* |
| `--user-name NAME` | | `servers[].user_name` | *(来自登录)* |
| `--device-id ID` | `FIN_DEVICE_ID` | `servers[].device_id` | 随机 UUID |
| `--renderer ` | `FIN_RENDERER` | `renderer` | `mpv` |
| `--mpv` | | `renderer = "mpv"` | |
| `--chromecast [NAME]` | `FIN_CHROMECAST` | `last_chromecast` | |
| `--upnp [NAME]` | `FIN_UPNP` | `last_upnp` | |
| `-v`, `-vv` | *(日志级别)* | | `warn` |
音频相关的播放设置位于 TOML 子表下,通过 TUI 切换(参见[播放模式与效果](#playback-modes--effects)):
| TOML | 默认值 | 说明 |
|------|--------|------|
| `replaygain.mode` | `off` | `off` / `track` / `album` |
| `replaygain.preamp_db` | `0.0` | 以 dB 为单位的前置增益(在削波保护之前增加) |
| `replaygain.prevent_clip` | `true` | 限制增益,使得 `linear * peak <= 1.0` |
| `crossfade.mode` | `off` | `off` / `crossfade` / `mixed` |
| `crossfade.duration_secs` | `5.0` | 重叠窗口(秒) |
| `eq_enabled` | `false` | 切换 Rockbox 10 段均衡器流水线 |
| `[[eq_band_settings]]` | ISO 倍频程 | 10 个频段(参见[均衡器](#equalizer));兼容 Rockbox |
| `bass` | `0` | 低音架增益(整数 dB,范围 −24 到 +24) |
| `treble` | `0` | 高音架增益(整数 dB,范围 −24 到 +24) |
| `bass_cutoff` | `0` | 低音架截止频率(Hz,`0` 表示 Rockbox 默认 200) |
| `treble_cutoff` | `0` | 高音架截止频率(Hz,`0` 表示 Rockbox 默认 3500) |
使用 `fin config --path` 查看磁盘上的配置文件路径;使用 `fin config --show` 打印当前配置。
## 多服务器支持
fin 可以与任意多个服务器进行认证 — Jellyfin 和 Subsonic 可混合使用,并且它们的凭据会并行保存在一个配置文件中:
```bash
fin login https://home.example.com --name home
fin login https://work.example.com --name work
fin login https://mom.dyndns.example --name mom
fin server # 列出所有服务器(▍ 标记当前服务器)
fin server switch work # 将 `work` 设为活动服务器
fin server rm mom # 移除一个服务器
fin server rename home casa # 将 `home` 重命名为 `casa`
# 单次执行 — 不改变当前指针的情况下访问 `work`:
fin --server-name work search "spirited away"
fin --server-name work play "spirited away"
```
在 TUI 中,“设置”屏幕会显示所有保存的服务器;在某个服务器上按 **Enter** 即可切换到它。在 TUI 中任何位置按 **`t`** 会循环到下一个服务器,无需离开当前屏幕。
## 子命令
```bash
fin # 启动 TUI(默认)
fin login [--name N] # 登录并保存服务器 `N` 的凭据
fin logout [--name N] # 移除服务器 `N`(默认为当前服务器)
fin server # 列出保存的服务器
fin server switch # 更改活动服务器
fin server rm # 移除一个服务器
fin server rename # 重命名
fin search # 从活动媒体库打印匹配结果
fin play # 搜索并播放最佳匹配
fin queue # 搜索并追加到当前队列
fin devices # 列出局域网中的 Chromecast 和 UPnP MediaRenderer
fin playlists # 列出播放列表
fin playlists --list # 导出一个播放列表的项目
fin config --show|--path # 检查配置
```
## TUI 快捷键绑定
标签页顺序 — 默认屏幕是**音乐**:
`1` 音乐 • `2` 视频 • `3` 播放列表 • `4` 收藏 • `5` 队列 • `6` 搜索 • `7` 设备 • `8` 设置
**视频**标签页仅适用于 Jellyfin — Subsonic 没有视频 API,因此在 Subsonic 服务器上该标签页会隐藏,`Tab` / `Shift+Tab` 会跳过它,按 `2` 会显示提示。其他数字键保持原有功能。
| 按键 | 动作 |
|------|------|
| `?` | 显示/隐藏完整键盘快捷键帮助弹窗 |
| `Tab` / `Shift+Tab` | 下一个/上一个屏幕 |
| `1` … `8` | 跳转到音乐/视频/播放列表/收藏/队列/搜索/设备/设置 |
| `/` | 跳转到搜索并将焦点置于输入框 |
| `↑` `↓` / `k` `j` | 移动选择 |
| `PgUp` / `PgDown` | 跳转 10 行 |
| `Enter` | **深入**一个容器(专辑、剧集、播放列表)— 播放一个叶子项(曲目、分集、电影);在队列上 → **跳转**播放头到所选条目;在设备上 → 连接到所选 Chromecast / UPnP 渲染器;在设置上 → 切换服务器 |
| `x` | **不深入**,直接将高亮容器作为一个队列播放(专辑 → 所有曲目,播放列表 → 所有项目) |
| `Shift+X` | **随机播放** — 高亮容器时与 `x` 作用相同;在平面视图(收藏、视频、打开的专辑/播放列表)中,随机排列整个列表并启用随机模式 |
| `a` | 将高亮项目加入队列 |
| `n` | **下一首**播放高亮项目 |
| `Shift+L` / `Shift+D` | **喜欢/不喜欢** — 将高亮项目(或当前播放曲目)添加到/移出收藏;Jellyfin 收藏,Subsonic 星标 |
| `z` | 切换随机播放 |
| `Shift+R` | 循环重复模式(关闭 → 全部 → 单曲) |
| `g` | 循环 ReplayGain(关闭 → 曲目 → 专辑) |
| `f` / `Shift+F` | 循环交叉渐变模式 / 循环交叉渐变时长(3、5、8、12 秒) |
| `Shift+E` | 切换 10 段 Rockbox 均衡器 |
| `[` / `]` |(设置中)选择上一个/下一个均衡器频段 |
| `Shift+↑` / `Shift+↓` |(设置中)微调所选均衡器频段的增益 ±1 dB |
| `b` / `Shift+B` | 低音架 −1 dB / +1 dB |
| `y` / `Shift+Y` | 高音架 −1 dB / +1 dB |
| `Space` 或 `p` | 暂停/继续 |
| `s` | 停止 |
| `<` / `>` 或 `h` / `l` | 上一首/下一首曲目 |
| `+` / `-` | 音量增大/减小 |
| `m` | 切换到本地渲染器 |
| `t` | 循环到下一个保存的服务器 |
| `d` |(队列屏幕)移除高亮条目 |
| `Shift+C` |(队列屏幕)清空整个队列 |
| `Esc` | 退出当前深入层级(返回父列表) |
| `r` | 刷新当前视图 |
相似文章
jellyfin/jellyfin
Jellyfin 是一款免费开源的媒体服务器,用于管理和流式传输个人媒体收藏,是 Emby 和 Plex 等专有系统的替代方案。
tinysub: 适用于 Open Subsonic 兼容音乐服务器的功能齐全的网页播放器
tinysub 是一个功能齐全的网页播放器,适用于像 Navidrome 和 Gonic 这样的 Open Subsonic 兼容音乐服务器,使用 Svelte 构建以实现高性能和桌面般的体验。
andrewrabert/jellium-desktop
Jellium Desktop 是一款基于 CEF 和 mpv 的非官方 Jellyfin 桌面客户端,提供 Linux、macOS 和 Windows 的跨平台下载。
Fincept-Corporation/FinceptTerminal
FinceptTerminal 是一个开源金融智能平台,采用 C++20 和 Qt6 构建,提供 CFA 级别的分析工具、AI 自动化和全面的数据连接功能,适用于股票研究、投资组合管理和交易。
@QCXINT_: 直接在终端观看电影、电视剧和动漫。无需浏览器。无广告。无臃肿界面。MovieBox-TUI 是一个轻…
MovieBox-TUI 是一个用 Rust 编写的轻量级开源终端应用程序,允许用户直接从 CLI 流媒体播放电影、电视剧和动漫,无需浏览器,也没有广告。