fix(player): 修复竖滑上一集不自动播放

This commit is contained in:
Zhou Weidong committed 2026-10-26 13:43:43 +08:00
1 parent df36890b48
commit 516593499c
10 files changed
+264 -80

No files matched your search

+12 -8
View File
@@ -67,15 +67,19 @@ Future<void> _placeNeighbor(PlaybackSession session, _PlayerSlot? slot) async {
await session._retire(slot);
}
/// 当前集已经出画后,静默准备上一集和下一集。
void _warmNeighbors(PlaybackSession session) {
/// 当前集已经出画后,按手势方向静默准备上一集和下一集。
void _warmNeighbors(PlaybackSession session, {bool preferredNext = true}) {
final request = session._generation;
session._preloadTask = () async {
await Future.wait([
_warmOne(session, request, session._nextIndex, next: true),
_warmOne(session, request, session._previousIndex, next: false),
]);
}();
final nextTask = _warmOne(session, request, session._nextIndex, next: true);
final previousTask = _warmOne(
session,
request,
session._previousIndex,
next: false,
);
session._preloadTask = Future.wait(
preferredNext ? [nextTask, previousTask] : [previousTask, nextTask],
).then<void>((_) {});
}
Future<void> _warmOne(
+12 -35
View File
@@ -8,6 +8,7 @@ import '../models/player_port.dart';
import 'video_player_port.dart';
part 'playback_neighbors.dart';
part 'playback_session_controls.dart';
/// 新纹理第一帧常是黑的,旧画面只盖住这一小段。
const Duration _qualityHandoffHold = Duration(milliseconds: 200);
@@ -40,6 +41,7 @@ class PlaybackSession extends ChangeNotifier {
final Future<void> Function()? waitForFrame;
final PlaybackCoordinator _coordinator;
final Set<_PlayerSlot> _live = {};
final Set<String> _pausedEpisodeIds = {};
_PlayerSlot? _active;
_PlayerSlot? _next;
_PlayerSlot? _previous;
@@ -106,15 +108,6 @@ class PlaybackSession extends ChangeNotifier {
return null;
}
/// 清晰度切换时盖住黑帧的旧播放器。只在仍由会话持有时交给界面。
PlayerPort? handoffAt(int index) {
final slot = _handoff;
if (_closed || slot == null || slot.retiring || slot.index != index) {
return null;
}
return slot.player;
}
/// 队列重排后把当前仍在播放的 slot 映射到新索引,不重新创建播放器。
void remapCurrentIndex(int index, {int? preloadIndex, int? previousIndex}) {
if (_closed || index < 0 || index >= episodes.length) return;
@@ -214,10 +207,9 @@ class PlaybackSession extends ChangeNotifier {
int? previousIndex,
}) async {
if (_closed || index < 0 || index >= episodes.length) return;
// 切到另一集时,上一集按下的暂停不跟着走:滑过去就应该自动播放。
// 重复选中同一集(例如页面重新可见)不在这里恢复,尊重用户按下的暂停。
// 新集默认起播;用户手动暂停过的同一集滑回时继续尊重暂停。
if (!_selected || index != _currentIndex) {
_userWantsPlay = true;
_userWantsPlay = !_pausedEpisodeIds.contains(episodes[index].id);
}
final request = ++_generation;
_selected = true;
@@ -256,7 +248,10 @@ class PlaybackSession extends ChangeNotifier {
target = old;
return;
}
if (old != null) await old.player.pause();
if (old != null) {
await old.player.pause();
old.playing = false;
}
final warmNext = _next;
final warmPrevious = _previous;
_active = null;
@@ -369,7 +364,10 @@ class PlaybackSession extends ChangeNotifier {
_handoff = previous;
_active = slot;
shown = true;
if (previous != null) await previous!.player.pause();
if (previous != null) {
await previous!.player.pause();
previous!.playing = false;
}
_notify();
});
if (!shown || _active != slot) return null;
@@ -422,27 +420,6 @@ class PlaybackSession extends ChangeNotifier {
slot.playing = shouldPlay;
}
void setAppResumed(bool value) {
_appResumed = value;
_syncPlayback();
}
void setRouteVisible(bool value) {
_routeVisible = value;
_syncPlayback();
}
void setOverlayOpen(bool value) {
_overlayOpen = value;
_syncPlayback();
}
void setUserWantsPlay(bool value) {
_userWantsPlay = value;
_syncPlayback();
_notify();
}
void _syncPlayback() {
if (_closed) return;
if (_visible && _selected && active == null) {
@@ -0,0 +1,54 @@
// Author: fruit.com.cn
part of 'playback_session.dart';
/// 播放会话的可见性、用户意图与相邻集预热控制。
extension PlaybackSessionControls on PlaybackSession {
/// 滑动手势开始时按方向优先准备相邻集,不改变当前集播放状态。
void prewarmNeighbors({required bool forward}) {
if (!_visible || _overlayOpen || _active?.prepared != true) return;
_warmNeighbors(this, preferredNext: forward);
}
/// 清晰度切换时盖住黑帧的旧播放器。只在仍由会话持有时交给界面。
PlayerPort? handoffAt(int index) {
final slot = _handoff;
if (_closed || slot == null || slot.retiring || slot.index != index) {
return null;
}
return slot.player;
}
/// 同步应用前台状态并恢复或暂停当前集。
void setAppResumed(bool value) {
_appResumed = value;
_syncPlayback();
}
/// 同步播放器路由是否可见。
void setRouteVisible(bool value) {
_routeVisible = value;
_syncPlayback();
}
/// 同步浮层是否遮挡播放器。
void setOverlayOpen(bool value) {
_overlayOpen = value;
_syncPlayback();
}
/// 记录用户播放意图;手动暂停的剧集滑回时不再自动起播。
void setUserWantsPlay(bool value) {
if (episodes.isNotEmpty) {
final episodeId = episodes[_currentIndex].id;
if (value) {
_pausedEpisodeIds.remove(episodeId);
} else {
_pausedEpisodeIds.add(episodeId);
}
}
_userWantsPlay = value;
_syncPlayback();
_notify();
}
}