fix(player): 隔离播放资源所有权并修复黑屏
This commit is contained in:
1 parent
54eb5a60a8
commit
bb2c729a7e
9 files changed
+223
-25
No files matched your search
@@ -90,7 +90,7 @@ class PlayerPage extends StatefulWidget {
|
||||
this.wallet,
|
||||
this.downloads,
|
||||
this.handoff,
|
||||
this.isolatePlaybackSession = false,
|
||||
this.revealAfterFirstFrame = false,
|
||||
});
|
||||
|
||||
final Drama drama;
|
||||
@@ -118,7 +118,7 @@ class PlayerPage extends StatefulWidget {
|
||||
final WalletController? wallet;
|
||||
final DownloadController? downloads;
|
||||
final PlayerPageHandoff? handoff;
|
||||
final bool isolatePlaybackSession;
|
||||
final bool revealAfterFirstFrame;
|
||||
|
||||
@override
|
||||
State<PlayerPage> createState() => _PlayerPageState();
|
||||
@@ -141,6 +141,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
DateTime? _swipeStartedAt;
|
||||
bool _swipePrewarmCaptured = false;
|
||||
bool _presentationActive = false;
|
||||
late bool _firstFrameReady;
|
||||
bool _leavingHandoff = false;
|
||||
bool _preparingFullPlayer = false;
|
||||
final Set<String> _precachedPosterUrls = {};
|
||||
@@ -152,6 +153,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_firstFrameReady = !widget.revealAfterFirstFrame;
|
||||
final handoff = widget.handoff;
|
||||
logic = PlayerBinding().create(
|
||||
history: context.read<WatchHistoryRepository>(),
|
||||
@@ -169,12 +171,18 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
logic.start(
|
||||
factory: context.read<PlayerFactory>(),
|
||||
coordinator: handoff == null && !widget.isolatePlaybackSession
|
||||
coordinator: widget.embedded
|
||||
? context.read<PlaybackCoordinator>()
|
||||
: PlaybackCoordinator(),
|
||||
initialUserWantsPlay: handoff?.sourceUserWantsPlay ?? true,
|
||||
);
|
||||
_pageController = logic.pages;
|
||||
if (kDebugMode && widget.revealAfterFirstFrame) {
|
||||
debugPrint(
|
||||
'[player-entry] phase=waiting-first-frame '
|
||||
'session=${identityHashCode(logic.session)}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -594,6 +602,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
PlayerRenderStack(
|
||||
pageController: _pageController,
|
||||
slots: _renderSlots(indices),
|
||||
onCurrentVideoVisible: _handleCurrentVideoVisible,
|
||||
),
|
||||
pageLayer,
|
||||
],
|
||||
@@ -660,16 +669,37 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
),
|
||||
),
|
||||
);
|
||||
if (widget.handoff == null) return player;
|
||||
final revealContent =
|
||||
!widget.revealAfterFirstFrame ||
|
||||
_firstFrameReady ||
|
||||
logic.session.isLocked ||
|
||||
logic.ticketError != null ||
|
||||
logic.blockedEpisodeId != null ||
|
||||
logic.session.error != null;
|
||||
final presentedPlayer = widget.revealAfterFirstFrame
|
||||
? Opacity(opacity: revealContent ? 1 : 0, child: player)
|
||||
: player;
|
||||
if (widget.handoff == null) return presentedPlayer;
|
||||
return PopScope<void>(
|
||||
canPop: _leavingHandoff,
|
||||
onPopInvokedWithResult: (didPop, _) {
|
||||
if (!didPop) unawaited(_leaveHandoff(context));
|
||||
},
|
||||
child: player,
|
||||
child: presentedPlayer,
|
||||
);
|
||||
}
|
||||
|
||||
void _handleCurrentVideoVisible() {
|
||||
if (!mounted || _firstFrameReady) return;
|
||||
setState(() => _firstFrameReady = true);
|
||||
if (kDebugMode) {
|
||||
debugPrint(
|
||||
'[player-entry] phase=ready '
|
||||
'session=${identityHashCode(logic.session)}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _openCurrentMore() {
|
||||
final entry = logic.queue.entryAt(logic.session.currentIndex);
|
||||
_openMore(context, entry.episode);
|
||||
@@ -1176,13 +1206,18 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
_logFullPlayerRoute('present');
|
||||
setState(() => _presentationActive = true);
|
||||
final route = Navigator.of(context).push<void>(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => PlayerPage(
|
||||
PageRouteBuilder<void>(
|
||||
opaque: false,
|
||||
barrierDismissible: false,
|
||||
transitionDuration: Duration.zero,
|
||||
reverseTransitionDuration: Duration.zero,
|
||||
pageBuilder: (_, _, _) => PlayerPage(
|
||||
drama: seriesDrama,
|
||||
initialIndex: episodeIndex,
|
||||
handoff: handoff,
|
||||
wallet: logic.wallet,
|
||||
downloads: logic.downloads,
|
||||
revealAfterFirstFrame: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user