fix(player): 使用雪碧图预热首帧兜底

This commit is contained in:
Zhou Weidong committed 2026-10-26 14:21:52 +08:00
1 parent 48b4e67d34
commit 70d8e0f982
13 files changed
+207 -322

No files matched your search

@@ -18,6 +18,7 @@ class PlayerVideoSurface extends StatefulWidget {
required this.theater,
this.handoff,
this.openingFrame,
this.openingFrameReady = false,
this.holdOpeningUntilFirstFrame = false,
this.preparedFrameAvailable = false,
});
@@ -28,6 +29,9 @@ class PlayerVideoSurface extends StatefulWidget {
/// 解码出第一帧之前垫上的视频首帧,没有则为空。
final Widget? openingFrame;
/// 当前集雪碧图 t=0 是否已在共享缓存中可用。
final bool openingFrameReady;
/// 播放中的新片源在位置首次前进前继续显示封面,避免混入未出帧纹理。
final bool holdOpeningUntilFirstFrame;
@@ -73,10 +77,10 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
final controller = widget.controller;
final handoff = _liveHandoff(controller);
final firstFrameSeen = _trackFrameState(controller, value);
final firstFrameReady =
widget.preparedFrameAvailable || firstFrameSeen;
final firstFrameReady = widget.preparedFrameAvailable || firstFrameSeen;
final textureReady = _shouldReveal(value, handoff != null);
final reveal = textureReady &&
final reveal =
textureReady &&
(!widget.holdOpeningUntilFirstFrame ||
widget.preparedFrameAvailable ||
firstFrameReady ||
@@ -86,13 +90,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
final showOpening =
widget.openingFrame != null && handoff == null && !reveal;
_logStateChange(value);
_logLayerState(
value,
handoff,
reveal,
firstFrameReady,
showOpening,
);
_logLayerState(value, handoff, reveal, firstFrameReady, showOpening);
return Stack(
fit: StackFit.expand,
children: [
@@ -203,10 +201,20 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
: !firstFrameReady && widget.holdOpeningUntilFirstFrame
? 'awaiting-first-frame'
: 'reveal';
final fallback = handoff != null
? 'handoff'
: showOpening
? widget.openingFrameReady
? 'thumbnails-first-frame'
: 'black'
: reveal
? 'video'
: 'black';
final signature =
'warm=${widget.preparedFrameAvailable ? 1 : 0} '
'frame=${firstFrameReady ? 1 : 0} '
'cover=${showOpening ? 1 : 0} '
'thumbnails=${widget.openingFrameReady ? 'ready' : 'pending'} '
'fallback=$fallback '
'video=${reveal ? 1 : 0} handoff=${handoff == null ? 0 : 1} '
'init=${value?.isInitialized == true ? 1 : 0} '
'playing=${value?.isPlaying == true ? 1 : 0} '