fix(player): 隔离播放资源所有权并修复黑屏

This commit is contained in:
Zhou Weidong committed 2026-10-26 17:03:19 +08:00
1 parent 54eb5a60a8
commit bb2c729a7e
9 files changed
+223 -25

No files matched your search

@@ -52,10 +52,12 @@ class PlayerRenderStack extends StatefulWidget {
super.key,
required this.pageController,
required this.slots,
this.onCurrentVideoVisible,
});
final PageController pageController;
final Map<PlayerRenderSlotRole, PlayerRenderSlotData> slots;
final VoidCallback? onCurrentVideoVisible;
@override
State<PlayerRenderStack> createState() => _PlayerRenderStackState();
@@ -68,7 +70,10 @@ class _PlayerRenderStackState extends State<PlayerRenderStack> {
void initState() {
super.initState();
_lastCurrentIndex = _currentSlot.index;
_log('init current=${_lastCurrentIndex ?? '-'}');
_log(
'init current=${_lastCurrentIndex ?? '-'} '
'pageController=${identityHashCode(widget.pageController)}',
);
}
@override
@@ -86,7 +91,10 @@ class _PlayerRenderStackState extends State<PlayerRenderStack> {
@override
void dispose() {
_log('dispose current=${_lastCurrentIndex ?? '-'}');
_log(
'dispose current=${_lastCurrentIndex ?? '-'} '
'pageController=${identityHashCode(widget.pageController)}',
);
super.dispose();
}
@@ -189,6 +197,9 @@ class _PlayerRenderStackState extends State<PlayerRenderStack> {
fallback: slot.fallback,
warmSlotReused: slot.warmSlotReused,
waitForPlaybackFrame: slot.waitForPlaybackFrame,
onVideoVisible: slot.role == PlayerRenderSlotRole.current
? widget.onCurrentVideoVisible
: null,
),
),
);
@@ -28,6 +28,7 @@ class PlayerVideoSurface extends StatefulWidget {
this.debugSlot = 'default',
this.debugIndex,
this.showFallbackBackground = true,
this.onVideoVisible,
});
final VideoPlayerController? controller;
@@ -57,6 +58,7 @@ class PlayerVideoSurface extends StatefulWidget {
final bool showFallbackBackground;
final String videoUrl;
final bool theater;
final VoidCallback? onVideoVisible;
@override
State<PlayerVideoSurface> createState() => _PlayerVideoSurfaceState();
@@ -73,6 +75,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface>
bool _confirmationScheduled = false;
bool _transitioning = false;
bool _videoVisible = false;
bool _videoVisibleNotified = false;
String? _lastLayerState;
@override
@@ -279,6 +282,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface>
});
}
_logLayer('video', widget.controller?.value);
_notifyVideoVisible();
return;
}
if (initial) {
@@ -303,6 +307,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface>
_placeholderSnapshot = null;
});
_logLayer('fade-end', widget.controller?.value);
_notifyVideoVisible();
}
void _resetForControllerChange() {
@@ -314,9 +319,20 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface>
_confirmationScheduled = false;
_transitioning = false;
_videoVisible = false;
_videoVisibleNotified = false;
_lastLayerState = null;
}
void _notifyVideoVisible() {
if (_videoVisibleNotified) return;
_videoVisibleNotified = true;
final callback = widget.onVideoVisible;
if (callback == null) return;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) callback();
});
}
void _logLayer(String phase, VideoPlayerValue? value) {
if (!kDebugMode) return;
final fallback = phase == 'video' || phase == 'fade-end'