From b439d1cb8c791b5516788b5eaaa5ba03ad8d50bd Mon Sep 17 00:00:00 2001 From: lxh2875931338 Date: Sat, 31 Oct 2026 21:50:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(playback):=20=E6=92=AD=E6=94=BE=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=8E=BB=E9=87=8D=EF=BC=8C=E9=81=BF=E5=85=8D=E5=90=8C?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E7=82=B9=E5=87=BB=E8=A7=A6=E5=8F=91=E5=A4=9A?= =?UTF-8?q?=E6=AC=A1=20open?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 日志证据(21:45):同一次切歌 play() 被调用 3 次 (31.798、32.839、33.442),互相顶掉,起播拖到 2977ms。 - _playCurrent 增加 800ms 同曲去重:同 index 且短时间内重复的请求直接忽略 - 实测:点击后 play() 只调用 1 次,起播 2977ms -> 2098ms 说明:剩余 ~2s 主要是 mpv 建连 + 首包 + 音频输出, 跨 FRP 链路属于正常范围,后续可单独调 mpv 参数优化。 --- lib/services/audio_service.dart | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart index 5097dc6..684c165 100644 --- a/lib/services/audio_service.dart +++ b/lib/services/audio_service.dart @@ -119,6 +119,10 @@ class AudioService extends ChangeNotifier { int _recoveryAttempts = 0; static const int _maxRecoveryAttempts = 3; + /// 播放请求去重(同一次点击可能从多个入口触发) + DateTime? _lastPlayRequestAt; + int _lastPlayRequestIndex = -1; + /// 当前歌曲开始加载的时间,用于"起播看门狗": /// 有些情况下 mpv 的 playing 已经是 true,但 position 永远是 0、 /// 也不发 buffering / error(实测公网链路可静默卡 75s+)。 @@ -321,6 +325,18 @@ class AudioService extends ChangeNotifier { return; } + // 去重:同一次点击可能从多个入口触发(列表 onTap + 控制器 + 通知), + // 反复 open 会互相顶掉,表现为"点了要等好几秒才出声"。 + final now = DateTime.now(); + if (_lastPlayRequestIndex == _currentIndex && + _lastPlayRequestAt != null && + now.difference(_lastPlayRequestAt!) < const Duration(milliseconds: 800)) { + debugPrint('⏭️ [AudioService] 忽略重复播放请求(index=$_currentIndex)'); + return; + } + _lastPlayRequestAt = now; + _lastPlayRequestIndex = _currentIndex; + // 「最新请求胜出」:不再因为 _isChangingTrack 为 true 就直接丢弃请求。 // 旧请求会通过 epoch 校验自行放弃后续步骤,避免和新的切歌互相覆盖。 final epoch = ++_switchEpoch;