功能介绍
轻听是 Android / Windows 双端的音乐应用——装上就能用,核心功能全程不需要联网。
在线能力是可选增强,而且被设计成一层可插拔的东西:音源包。 没装音源包时应用依然完整,只是在线搜索与播放不出现。
下面按「本地能力」「在线聚合」「音源包机制」「两端差异」「已知限制」几块说明。 想直接看怎么装音源,去如何设置音源。
本地能力(开箱即用,无需音源包)
| 能力 | Android | Windows |
|---|---|---|
| 扫描本地目录建库 | ✅ 全盘 / 指定文件夹,可设最小文件大小过滤 | ✅ 目录级管理 |
| 支持格式 | MP3 / FLAC / WAV / OGG / AAC / M4A | MP3 / FLAC / WAV / OGG / AAC / M4A |
| 播放与队列 | ✅ 顺序 / 列表循环 / 单曲循环 / 随机 | ✅ 同 |
| 歌词 | ✅ 滚动歌词、歌词翻译、字号调节、全屏歌词 | ✅ 桌面歌词窗口 |
| 下载管理 | ✅ 后台持续下载、进度实时、音质可选 | ✅ 进度写库、任务列表 |
| 听歌统计 | ✅ 累计播放 / 收藏 / 听过 / 活跃天数 | ✅ 播放次数、时长、热门曲目与歌手排行 |
| 收藏与歌单 | ✅ 自建歌单,登录后可云同步 | ✅ 自建歌单,与后端账号云同步 |
| 不喜欢列表 | ✅ 屏蔽单曲或整个歌手 | ✅ 同 |
本地曲库
Android 支持整盘扫描,也可以只指定某几个文件夹;带最小文件大小过滤, 避免把提示音、缓存碎片一起收进库。Windows 是目录级管理。
扫描入库时会尝试读取音频元数据(标题 / 艺术家 / 专辑 / 时长), 原生元数据缺失的字段回落到按文件名解析——所以命名规范的文件也能正常显示。
播放与队列
四种循环模式:顺序、列表循环、单曲循环、随机。除此之外还有:
- 下一首播放:把歌插到队列下一位,不打断当前播放
- 播放倍速:可设默认值,播放页临时调速
- 播放失败自动切歌:连续失败多首后停下并提示,不会无限跳
听歌统计
Android 端四张卡片:累计播放 / 收藏歌曲 / 听过歌曲 / 活跃天数。 Windows 端更偏向排行:播放次数、时长、热门曲目与歌手排行。
不喜欢列表
可以屏蔽一首歌,也可以屏蔽整个歌手。被屏蔽的内容:
- 列表里置灰(能看到但一眼知道被屏蔽了)
- 不进入播放队列,自动衔接时直接跳过
- 不参与每日推荐一类的推荐流
- 点播的单曲永远保留——你明确点了它,就以你的操作为准
屏蔽规则两端同语义,可以在设置页统一管理、逐条解除。
在线聚合(需安装音源包)
在线能力全部由音源包提供,仓库本身不包含任何第三方取链实现。
数据面(搜索 / 歌单 / 歌词 / 封面)随官方数据包下发,取链面由播放包承担。 拆成两个包的好处是:风险较高的取链实现可以独立更换,而搜索、歌单这些体验不受牵连。
支持的音源
音源清单由音源包自己声明并下发,客户端不内置任何白名单——包里加一行, 该源立刻在两端可选、可搜、可播放。
| 音源 | id | 短名 |
|---|---|---|
| 网易云音乐 | wyy | 网易 |
| QQ 音乐 | qq | |
| 酷我音乐 | kw | 酷我 |
| 酷狗音乐 | kg | 酷狗 |
| 哔哩哔哩 | bili | B 站 |
| 咪咕音乐 | migu | 咪咕 |
功能面因源而异
不是每个源都有全部入口。比如 B 站没有歌单载体,「歌单广场」对它永远是空的—— 客户端会按音源包声明的功能面自动隐藏这些入口,而不是给你一个空列表。
具体来说,每个源会声明自己有没有:排行榜 / 歌单 / 歌手页 / 专辑 / 新歌流 五项能力。没有的入口直接不渲染。
兼容 LX 音源脚本
这是轻听音源体系里最实用的一点:播放包内置一个 LX 自定义源脚本宿主。
只要是按 LX 自定义源协议写的脚本(注册 lx.on(...) 事件、通过 lx.send 回数据、 用 utils.crypto / utils.buffer 做加解密),无需改动即可装载, 并且同一份脚本在 Android 与 Windows 两端跑出同样的结果。
宿主为了跑通这些脚本做过的事,都写在开源仓库里:
| 能力 | 说明 |
|---|---|
| 协议模拟 | 提供符合协议的 lx 对象(事件注册、请求回调、脚本自述)与 utils.crypto(md5 / AES)、utils.buffer(utf8 / hex / base64 互转) |
| 环境桩 | 脚本里常见的 process / window 全局探测与定时器反调试被安全接住,不因环境差异崩掉 |
| 逐字节保全 | 混淆脚本体在构建流水线里被逐字节还原——打包器重打印语法树会破坏脚本自身的完整性自校验,导致解密轮转不收敛、陷入同步忙循环 |
| 挂死守卫 | 每条脚本在沙箱里被实际执行一遍,看门狗盯住挂死,挂死即中止构建,坏脚本发不出去 |
一个包里可以并存多条线路
线路类型有 LX 脚本、平台官方接口、聚合脚本几种,各有分工。某条不通时自动换下一条; 本档线路全灭时还会跨源兜底救回,尽量不让你听到失败。
兼容不等于放权
脚本仍然跑在沙箱里,能用的只有宿主注入的 request 通道—— fetch / XMLHttpRequest / WebSocket / Worker / 文件系统全是 undefined, 也够不到宿主与系统的任何原生桥。安装前还会先做内容安全扫描。
在线能力清单
- 搜索:跨源聚合,每页条数按音源包声明的上限走 (各源上限不同:酷我 / 网易 100 条,QQ 50 条,酷狗 30 条,B 站 / 咪咕 20 条)
- 歌单广场 / 热门歌单 / 每日推荐:排序选项也由包声明 (如酷狗的「最热 / 最新 / 推荐」),空数组则表示该源不支持排序、不渲染选择器
- 排行榜 / 新歌速递 / 热门搜索词
- 歌手页 / 专辑页:各平台能力不齐,缺的字段留空而非编造
- 歌词:普通 LRC + 翻译;音源包支持时另有逐字歌词与罗马音 / 注音
- 同歌多源:播放时可切换音源,优先选可用的高音质来源
- 在线播放缓存:Android 端边播边缓存到本地(上限可调),重复播放不走网络
- 音质:标准 128k / 高品 320k / 无损 FLAC,播放与下载音质相互独立
关于「换源」的诚实说明
本应用通过换源机制从各平台公开接口取播放地址。这些数据并非官方授权、也不保证准确, 可能出现翻唱、Live、串曲或不同平台版本。这是这类工具的固有特性,不是可修的缺陷。
如果某个平台没有版权或下架了,换个源通常能找到——这也是「同歌多源」存在的意义。
音源包机制(为什么这么设计)
传统的做法是客户端内置各家接口,接口一变就只能发新版 App。轻听把这部分拆出去:
┌─────────────┐ 安装/更新 ┌──────────────────┐
│ 客户端 │ ←────────────── │ 音源包(.js) │
│ (不含取链) │ │ 取链 + 数据面 │
└─────────────┘ └──────────────────┘
▲ ▲
│ 执行于本地引擎 │ 官方 ed25519 签名
│(Android: WebView V8) │ + 内容安全扫描
│(Windows: 引擎页) │三层安全边界
第一层:安装前的内容扫描
安装时扫包文本,命中宿主桥 / 自由外联 / 后台执行体等红线直接拒绝, 错误信息给出命中词与行号。fetch( / require( 按调用形态识别, backend.fetch(id) 这类正常写法不误伤。
第二层:官方签名
官方包带 ed25519 签名,客户端内置公钥硬校验,改一个字节就装不上。 play-official / meta-official 是官方保留 id,只有验签通过才能占用。
第三层:运行时能力收缴
包跑在本地引擎里,能用的只有 host.request 一个网络出口:
| 能力 | 包内状态 |
|---|---|
host.request | ✅ 唯一网络出口 |
fetch / XMLHttpRequest / WebSocket | ❌ undefined |
Worker / ServiceWorker / importScripts | ❌ undefined |
| 文件系统 | ❌ 无 |
即便包里有动态执行(eval / Function),也拿不到额外能力—— 出口已经封死了。这也正是扫描规则刻意不拦 eval( 的原因:拦了会误杀 crypto-js 这类主流库的环境探测,收益却是零。
多包并存与冒烟自检
- 多包并存:可同时装多份播放包,设置页选一份启用,切换即时热装载
- 冒烟自检:装完先拿真实歌曲取链 + Range 预检,不过就回滚, 不会把你卡在坏包上(更新场景回滚旧版,首次安装保留文件并标注「上次失败」)
- 失败原因可见:列表每行显示来源(链接 / 本地 / 官方)与最近失败原因
未安装播放包时,在线播放不可用,但本地音乐与在线搜索不受影响。
两端各自的特色
Android(qt-uniappx)
- 原生后台播放:锁屏 / 后台持续播放,通知栏控件齐全
- 桌面歌词:系统悬浮窗,逐行跟随、可拖动、可锁定(锁定后点击穿透,不影响 你操作下面的应用)。字号 / 颜色 / 字体可调并即时生效。 开关是运行期状态,每次启动默认关闭——避免常驻悬浮窗在你不知情时一直挂着
- 均衡器:五段(60Hz / 230Hz / 910Hz / 3.6kHz / 14kHz), 8 种预设(平直 / 流行 / 摇滚 / 古典 / 爵士 / 电子 / 低音增强 / 人声)
- 定时关闭:10 / 30 / 60 分钟后,或「播放完当前歌曲后」
- 同时播放:三档音频共存策略——不允许(独占)/ 部分场景(压低音量)/ 全部场景(完全同时播放)
- 下载管理:后台持续下载、同时下载数可调、文件名格式可选 (「歌手 - 歌名」或「歌名 - 歌手」)
- 音频缓存:边播边缓存,上限默认 1024 MB,可自定义(原生层最小 256 MB)
- 账号体系:邮箱 / 用户名登录、邮箱验证码找回密码、签到、编辑资料
- 收藏同步:登录后自动同步,断网暂存、联网补推;每次启动做存在性对账
- 公告与消息中心:开屏弹窗、首页跑马灯、消息中心未读红点
- 外观与皮肤:明暗模式 + 三套预置皮肤,自定义背景与配色; 宽屏设备(≥ 720px)自动切宽屏布局
Windows(qt-pc)
- HTTP Range 流式播放:边下边播,拖动进度条即时定位
- 本地文件导入:目录级管理,元数据优先读原生标签、缺失回落文件名
- 独立桌面歌词窗口:置顶、锁定 / 穿透、自定义样式
- 应用内更新:下载后校验完整性再安装,安装前强制验签
- 外观与快捷键:浅色 / 深色 / 跟随系统、封面色取色主题、全局快捷键
- 音源包机制:从链接安装,官方包支持自动更新,也可粘贴自定义直链
- 播放统计:播放次数、时长、热门曲目与歌手排行
题外:为什么没有批量操作
批量下载 / 批量收藏对服务器压力很大,而服务端是个人搭建的,承受不了。 这是明确的取舍,不是遗漏。
已知限制
- 不支持 APE / WMA / DSD(解码依赖 symphonia)
- 未安装音源包时搜索 / 榜单 / 在线歌单不可用(本地音乐不受影响)
- 部分音源的无损取址在无无损源时会回退到有损; 下载扩展名按实际返回的 URL 决定,不虚标
- 逐字歌词、罗马音仅在音源包支持时可用
- 桌面歌词、本地文件删除依赖系统权限,不同厂商机型入口位置有差异
- 鸿蒙系统暂未单独适配
- iOS 未正式发布(代码层面 UniAppX 可编译 iOS,但没有发行版)
- 部分上游接口可能因地区或网络环境不可达,此时换源通常可解