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;