fix(player): 观看全集进入后自动播放

This commit is contained in:
Zhou Weidong committed 2026-10-26 21:25:38 +08:00
1 parent 350d16db75
commit 37353dac15
5 files changed
+126 -6

No files matched your search

+17 -1
View File
@@ -13,8 +13,18 @@ class PlaybackCoordinator {
Future<bool> _acquire(PlaybackSession session, bool Function() valid) {
final result = _handoff.then((_) async {
if (!valid()) return false;
final previous = _owner;
if (kDebugMode) {
debugPrint(
'[player-coordinator] phase=acquire '
'session=${identityHashCode(session)} owner=${session.owner.name} '
'previous=${previous == null ? '-' : identityHashCode(previous)} '
'previousOwner=${previous?.owner.name ?? '-'} '
'previousLive=${previous?.livePlayerCount ?? 0} '
'same=${identical(previous, session)}',
);
}
if (_owner != session) {
final previous = _owner;
if (previous != null && previous.owner != session.owner) {
if (kDebugMode) {
debugPrint(
@@ -31,6 +41,12 @@ class PlaybackCoordinator {
if (!valid()) return false;
_owner = session;
}
if (kDebugMode) {
debugPrint(
'[player-coordinator] phase=acquired '
'session=${identityHashCode(session)} live=${session.livePlayerCount}',
);
}
return true;
});
_handoff = result.then<void>((_) {});
@@ -84,6 +84,11 @@ class PlaybackSession extends ChangeNotifier {
bool get canAutoAdvance => _mayPlay && !_loading && active != null;
bool get isLocked => !canPlay(currentEpisode);
String? get error => _error;
bool get debugAppResumed => _appResumed;
bool get debugRouteVisible => _routeVisible;
bool get debugOverlayOpen => _overlayOpen;
bool get debugVisible => _visible;
bool get debugMayPlay => _mayPlay;
// Includes initialization and asynchronous disposal, until native release ends.
int get livePlayerCount => _live.length;
bool get activeSlotActivated => _active?.activated ?? false;
@@ -254,6 +259,16 @@ class PlaybackSession extends ChangeNotifier {
bool? userWantsPlay,
}) async {
if (_closed || index < 0 || index >= episodes.length) return;
if (kDebugMode) {
debugPrint(
'[player-session] phase=select-enter session=${identityHashCode(this)} '
'owner=${owner.name} index=$index user=$_userWantsPlay '
'selected=$_selected current=$_currentIndex '
'appResumed=$_appResumed routeVisible=$_routeVisible '
'overlayOpen=$_overlayOpen visible=$_visible mayPlay=$_mayPlay '
'live=${_live.length}',
);
}
// 切换到不同剧集时恢复播放;仍停留在同一集时保留用户暂停。
if (userWantsPlay != null) {
_userWantsPlay = userWantsPlay;
@@ -465,6 +480,22 @@ class PlaybackSession extends ChangeNotifier {
Future<void> _applyPlayback(_PlayerSlot slot) async {
if (_closed || _active != slot || !slot.activated) return;
final shouldPlay = _mayPlay && slot.index == _currentIndex && !isLocked;
final video = slot.player is VideoPlayerPort
? slot.player as VideoPlayerPort
: null;
if (kDebugMode) {
debugPrint(
'[player-session] phase=apply-playback '
'session=${identityHashCode(this)} owner=${owner.name} '
'index=${slot.index} shouldPlay=$shouldPlay user=$_userWantsPlay '
'appResumed=$_appResumed routeVisible=$_routeVisible '
'overlayOpen=$_overlayOpen locked=$isLocked '
'player=${identityHashCode(slot.player)} '
'controller=${video == null ? '-' : identityHashCode(video.controller)} '
'isPlaying=${video?.controller.value.isPlaying ?? '-'} '
'slotPlaying=${slot.playing}',
);
}
if (shouldPlay == slot.playing) return;
if (shouldPlay) {
await slot.player.play();
@@ -472,6 +503,15 @@ class PlaybackSession extends ChangeNotifier {
await slot.player.pause();
}
slot.playing = shouldPlay;
if (kDebugMode) {
debugPrint(
'[player-session] phase=apply-playback-result '
'session=${identityHashCode(this)} index=${slot.index} '
'shouldPlay=$shouldPlay '
'isPlaying=${video?.controller.value.isPlaying ?? '-'} '
'slotPlaying=${slot.playing}',
);
}
}
void _syncPlayback() {
+2
View File
@@ -249,6 +249,8 @@ class PlayerLogic extends ChangeNotifier {
'[feed-session] phase=$phase session=${identityHashCode(session)} '
'index=${session.currentIndex} episode=${session.currentEpisode.id} '
'controller=${video == null ? '-' : identityHashCode(video.controller)} '
'user=${session.userWantsPlay} routeVisible=${session.debugRouteVisible} '
'appResumed=${session.debugAppResumed} overlayOpen=${session.debugOverlayOpen} '
'live=${session.livePlayerCount}',
);
}
+30 -3
View File
@@ -148,6 +148,7 @@ class _PlayerPageState extends State<PlayerPage>
bool _loadingRemoved = true;
bool _loadingFadeScheduled = false;
bool _loggedLoadingUiVisible = false;
bool _loggedStartConditions = false;
final PlayerHeartOverlayController _heartOverlayController =
PlayerHeartOverlayController();
final Set<String> _precachedPosterUrls = {};
@@ -160,6 +161,7 @@ class _PlayerPageState extends State<PlayerPage>
void initState() {
super.initState();
final handoff = widget.handoff;
final initialUserWantsPlay = handoff?.sourceUserWantsPlay ?? true;
logic = PlayerBinding().create(
history: context.read<WatchHistoryRepository>(),
playback: context.read<PlaybackRepository>(),
@@ -179,8 +181,21 @@ class _PlayerPageState extends State<PlayerPage>
coordinator: widget.embedded
? context.read<PlaybackCoordinator>()
: PlaybackCoordinator(),
initialUserWantsPlay: handoff?.sourceUserWantsPlay ?? true,
initialUserWantsPlay: initialUserWantsPlay,
);
if (kDebugMode) {
debugPrint(
'[player-start] phase=initialized '
'session=${identityHashCode(logic.session)} '
'initialUserWantsPlay=$initialUserWantsPlay '
'sessionUserWantsPlay=${logic.session.userWantsPlay} '
'active=${logic.active} embedded=${widget.embedded} '
'appResumed=${logic.session.debugAppResumed} '
'routeVisible=${logic.session.debugRouteVisible} '
'overlayOpen=${logic.session.debugOverlayOpen} '
'live=${logic.session.livePlayerCount}',
);
}
_pageController = logic.pages;
if (!widget.embedded &&
!logic.isEpisodeLocked(logic.session.currentEpisode)) {
@@ -575,6 +590,19 @@ class _PlayerPageState extends State<PlayerPage>
Widget _buildPlayer(BuildContext context) {
final interactions = context.watch<InteractionController>();
final l10n = AppLocalizations.of(context)!;
if (kDebugMode && !_loggedStartConditions) {
_loggedStartConditions = true;
debugPrint(
'[player-start] phase=first-build '
'session=${identityHashCode(logic.session)} '
'tickerMode=${TickerMode.valuesOf(context).enabled} '
'routeVisible=${logic.session.debugRouteVisible} '
'appResumed=${logic.session.debugAppResumed} '
'overlayOpen=${logic.session.debugOverlayOpen} '
'visible=${logic.session.debugVisible} '
'mayPlay=${logic.session.debugMayPlay}',
);
}
final indices = logic.visibleIndices;
final activePort = logic.session.active;
final activeVideo = activePort is VideoPlayerPort ? activePort : null;
@@ -1341,8 +1369,7 @@ class _PlayerPageState extends State<PlayerPage>
seriesEpisodes.insert(0, sourceEpisode);
episodeIndex = 0;
}
final sourceUserWantsPlay = logic.session.userWantsPlay;
final handoff = PlayerPageHandoff(sourceUserWantsPlay: sourceUserWantsPlay);
final handoff = PlayerPageHandoff(sourceUserWantsPlay: true);
_logFullPlayerRoute('present');
setState(() => _presentationActive = true);
final route = Navigator.of(context).push<void>(