Skip to content

v0.25.0

Choose a tag to compare

@deltrivx deltrivx released this 28 Sep 11:59
· 10 commits to main since this release

ToneCore v0.25.0

修锁屏媒体控件(作用域错误致 metadata 从未上报);修移动端歌词显示区域;推荐移入曲库;取消主页最近入库。

修复一:锁屏媒体控件从未生效(真因)

现象

加了 Media Session 之后,锁屏/通知栏依然只显示软件名「ToneCore 音乐中枢」,
没有专辑图、没有歌名歌手、也没有播放控制。

上一版误判

v0.23.0 我判断是 artwork 的 MIME 类型问题(一律写 image/png,而曲库多是 jpg)。
那个问题真实存在且已修,但不是主因 —— 修完锁屏依然没变。

真因(本次定位)

media 被声明在 usePlayer() 内部:

export function usePlayer() {
  ...
  const media = useMediaSession({...});   // ← 函数作用域
}

而 applyState() 是模块级函数,它末尾调用:

function applyState(r) {          // ← 模块级
  ...
  media.update();                 // ← 引用不到内部的 const
}

JS 里这会抛 ReferenceError: media is not defined。
而 applyState() 是每一次播放状态更新的必经之路 ——
于是 metadata 一次都没有成功上报,锁屏只能拿 <title> 兜底。

修法

把句柄提到模块级,调用处用可选链兜住未初始化:

let media = null;                                  // 模块级
function applyState(r) { ... media?.update(); }    // 安全
export function usePlayer() { ... media = useMediaSession({...}); }

教训:跨作用域调用必须在真实运行时验证,不能只看编译通过。
构建成功不代表运行时引用合法。

修复二:移动端歌词显示的是后面的歌词

用户点破了方向

我一直按「歌词不同步」在查(调 offset、加一键对齐),
用户指出:不是同步问题,是显示区域不足。确认后确实如此,且有两个叠加成因。

成因 1:滚动定位算错了基准

const target = el.offsetTop - box.clientHeight / 2 + el.clientHeight / 2;

offsetTop 相对最近的 positioned 祖先计算,
而 lyricBox 自身没有 position: relative ——
于是它相对更外层祖先算,把上方大碟的高度也算了进去。

移动端大碟在正上方(约 300px ≈ 9 行歌词),所以滚动严重过头;
桌面端是左右布局,横向不叠加,误差只有几十 px ——
这解释了为什么「只有移动端错」。

改用 rect 差值,只关心「目标行中心」与「可视区中心」的差,与定位上下文无关:

const boxRect = box.getBoundingClientRect();
const elRect  = el.getBoundingClientRect();
const delta = (elRect.top + elRect.height / 2) - (boxRect.top + boxRect.height / 2);
box.scrollTo({ top: Math.max(0, box.scrollTop + delta), behavior: 'smooth' });

成因 2:移动端歌词区本身被挤没了

竖向预算(iPhone 14,视口 844px):

区块 高度
顶栏 58px
底部控制区 ≈150px
大碟(min(42vh,300px),shrink-0) 300px
曲目信息 ≈70px
歌词区剩余 ≈266px(≈6.7 行)

大碟带 shrink-0,flex 压缩不了它,只能压歌词区。
把移动端大碟缩到 min(30vh,200px) 后,歌词区 ≈366px(≈9.2 行)。
桌面端保持 min(46vh,340px) 不变。

变更:在线推荐移入曲库页

按用户要求,从主页搬到曲库页(曲目列表之上)。

同时取消首页「最近入库」 —— 它与本地曲库列表完全重复,
首页一份、曲库页一份,等于把同样的歌摆两遍。
清理了主页脚本里的 recent / playHomeSong / 推荐相关死引用。

验证

npm run build     ✅ web + server 均通过
npm test          ✅ 15 项全过

待办

  • 锁屏需真机验证:Media Session 需先播起来才激活,且要求安全上下文
    (HTTPS 或 localhost)。当前访问若是 http://192.168.31.x:8090,
    浏览器会直接禁用 Media Session —— 需确认访问方式。
  • 酷我(kw)在线搜索封面:该平台不返回封面地址
  • 音源状态显示口径