fix(playback): 网络切换重连不再抢在切歌前面
日志(21:51,用户刚把手机切到有线): 16.828 尝试重连:为爱痴狂(从 78s 继续) ← 网络变化触发,但用户已点新歌 17.569 play(新歌) 18.128 尝试重连:Communications(从 0s) ← 两条流程交叠 23.669 Failed to open -> 30.459 起播 5568ms - _onNetworkChanged:去抖开始时记录 songId + playbackGeneration, 2s 后若已切歌则忽略本次重连 - _recoverFromStall:await 打开完成后校验 generation, 切歌了就放弃本次恢复,避免把旧歌重新打开
This commit is contained in:
@@ -649,6 +649,9 @@ class AudioService extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
_lastStallRecoveryAt = now;
|
_lastStallRecoveryAt = now;
|
||||||
|
|
||||||
|
// 恢复前记下代次:await 期间用户可能已经切歌,
|
||||||
|
// 不能把旧歌重新打开(否则就是"点了新歌却切回旧歌")。
|
||||||
|
final recoveryGeneration = _playbackGeneration;
|
||||||
final resumeAt = _lastKnownPosition > Duration.zero
|
final resumeAt = _lastKnownPosition > Duration.zero
|
||||||
? _lastKnownPosition
|
? _lastKnownPosition
|
||||||
: positionNotifier.value;
|
: positionNotifier.value;
|
||||||
@@ -659,6 +662,10 @@ class AudioService extends ChangeNotifier {
|
|||||||
_playReadyAt = null;
|
_playReadyAt = null;
|
||||||
_firstAudioReported = false;
|
_firstAudioReported = false;
|
||||||
await _playWithHeaders(url);
|
await _playWithHeaders(url);
|
||||||
|
if (_playbackGeneration != recoveryGeneration) {
|
||||||
|
debugPrint('⏭️ [AudioService] 恢复期间已切歌,放弃本次恢复');
|
||||||
|
return;
|
||||||
|
}
|
||||||
_playReadyAt = DateTime.now();
|
_playReadyAt = DateTime.now();
|
||||||
if (resumeAt > Duration.zero) {
|
if (resumeAt > Duration.zero) {
|
||||||
await PlaybackService().seek(resumeAt);
|
await PlaybackService().seek(resumeAt);
|
||||||
@@ -681,9 +688,18 @@ class AudioService extends ChangeNotifier {
|
|||||||
/// 这里做 3s 去抖:切换瞬间往往会连续触发多次网络接口变化。
|
/// 这里做 3s 去抖:切换瞬间往往会连续触发多次网络接口变化。
|
||||||
void _onNetworkChanged() {
|
void _onNetworkChanged() {
|
||||||
_networkDebounce?.cancel();
|
_networkDebounce?.cancel();
|
||||||
|
// 记录去抖开始时的歌:2 秒内用户可能已经切歌,
|
||||||
|
// 那时再去重连"上一首"就是异常切换(日志里出现过 78s 重连旧歌)。
|
||||||
|
final expectedSongId = _currentSong?.id;
|
||||||
|
final expectedGeneration = _playbackGeneration;
|
||||||
_networkDebounce = Timer(const Duration(seconds: 2), () {
|
_networkDebounce = Timer(const Duration(seconds: 2), () {
|
||||||
if (_currentSong == null) return;
|
if (_currentSong == null) return;
|
||||||
if (_isChangingTrack) return;
|
if (_isChangingTrack) return;
|
||||||
|
if (_currentSong?.id != expectedSongId ||
|
||||||
|
_playbackGeneration != expectedGeneration) {
|
||||||
|
debugPrint('🌐 [AudioService] 网络变化期间已切歌,忽略本次重连');
|
||||||
|
return;
|
||||||
|
}
|
||||||
debugPrint('🌐 [AudioService] 网络已切换,主动重连当前歌曲');
|
debugPrint('🌐 [AudioService] 网络已切换,主动重连当前歌曲');
|
||||||
_recoverFromStall(force: true);
|
_recoverFromStall(force: true);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user