fix(player): 预热直出并与视频统一封面布局

This commit is contained in:
Zhou Weidong committed 2026-10-26 14:12:42 +08:00
1 parent a3a79f7068
commit 48b4e67d34
9 files changed
+119 -104

No files matched your search

@@ -12,17 +12,19 @@ import '../../../core/theme/app_colors.dart';
import '../../../core/widgets/remote_image.dart';
import 'scrub_preview_card.dart';
const double _posterAspectRatio = 3 / 4;
const double _posterBlurSigma = 18;
/// 封面立即可见,雪碧图首帧解码完成后再覆盖封面。
Widget? playerOpeningFrame(String? thumbnailsUrl, {String? posterUrl}) {
Widget? playerOpeningFrame(
String? thumbnailsUrl, {
String? posterUrl,
BoxFit fit = BoxFit.cover,
}) {
final url = thumbnailsUrl?.trim() ?? '';
final poster = posterUrl?.trim() ?? '';
if (url.isEmpty && poster.isEmpty) return null;
return PlayerOpeningFrame(
thumbnailsUrl: url.isEmpty ? null : url,
posterUrl: poster.isEmpty ? null : poster,
fit: fit,
);
}
@@ -32,12 +34,14 @@ class PlayerOpeningFrame extends StatefulWidget {
super.key,
this.thumbnailsUrl,
this.posterUrl,
this.fit = BoxFit.cover,
this.loader,
this.cache,
});
final String? thumbnailsUrl;
final String? posterUrl;
final BoxFit fit;
final SpriteThumbnailAssetLoader? loader;
final OpeningFrameCache? cache;
@@ -85,39 +89,18 @@ class _PlayerOpeningFrameState extends State<PlayerOpeningFrame> {
children: [
const ColoredBox(color: AppColors.mediaBlack),
if (posterUrl != null)
Positioned.fill(
child: ImageFiltered(
key: const Key('player-opening-poster-blur'),
imageFilter: ui.ImageFilter.blur(
sigmaX: _posterBlurSigma,
sigmaY: _posterBlurSigma,
),
child: RemoteImage(
posterUrl,
key: const Key('player-opening-poster-backdrop'),
fit: BoxFit.cover,
fallbackColor: AppColors.mediaBlack,
),
),
),
if (posterUrl != null)
Center(
child: AspectRatio(
key: const Key('player-opening-poster-stage'),
aspectRatio: _posterAspectRatio,
child: RemoteImage(
posterUrl,
key: const Key('player-opening-poster'),
fit: BoxFit.cover,
fallbackColor: AppColors.mediaBlack,
),
),
RemoteImage(
posterUrl,
key: const Key('player-opening-poster'),
fit: widget.fit,
fallbackColor: AppColors.mediaBlack,
),
if (frame != null)
SpriteCropPreview(
key: const Key('player-opening-sprite'),
image: frame.image,
sourceRect: frame.sourceRect,
fit: widget.fit,
),
],
);