fix(player): 预解码观看全集首帧

This commit is contained in:
Zhou Weidong committed 2026-10-26 17:27:43 +08:00
1 parent 1fc8c4924e
commit c8ec481fc9
5 files changed
+145 -26

No files matched your search

@@ -6,11 +6,56 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../../core/config/app_config.dart';
class PreparedPlayerFrame {
const PreparedPlayerFrame({this.bytes, this.provider});
final Uint8List? bytes;
final ImageProvider<Object>? provider;
bool get isReady => bytes != null || provider != null;
}
class PlayerFrameCapture {
const PlayerFrameCapture._();
static const int budgetMilliseconds = 32;
static Future<PreparedPlayerFrame> captureAndPrecache({
required BuildContext context,
required GlobalKey boundaryKey,
required String source,
String? fallbackPosterUrl,
}) async {
final bytes = await capture(
context: context,
boundaryKey: boundaryKey,
source: source,
);
if (bytes != null) {
if (!context.mounted) return const PreparedPlayerFrame();
final provider = MemoryImage(bytes);
if (await _precache(context, provider, source: source, kind: 'capture')) {
_log(
'[player-entry] phase=frame-precached source=$source kind=capture',
);
return PreparedPlayerFrame(bytes: bytes, provider: provider);
}
}
final poster = fallbackPosterUrl?.trim() ?? '';
if (poster.isNotEmpty) {
if (!context.mounted) return const PreparedPlayerFrame();
final provider = NetworkImage(AppConfig.mediaUrl(poster));
if (await _precache(context, provider, source: source, kind: 'poster')) {
_log('[player-entry] phase=frame-precached source=$source kind=poster');
return PreparedPlayerFrame(provider: provider);
}
}
return const PreparedPlayerFrame();
}
static Future<Uint8List?> capture({
required BuildContext context,
required GlobalKey boundaryKey,
@@ -57,6 +102,32 @@ class PlayerFrameCapture {
}
}
static Future<bool> _precache(
BuildContext context,
ImageProvider<Object> provider, {
required String source,
required String kind,
}) async {
var failed = false;
try {
await precacheImage(
provider,
context,
onError: (_, _) {
failed = true;
},
);
} catch (_) {
failed = true;
}
if (failed) {
_log(
'[player-entry] phase=frame-precache-failed source=$source kind=$kind',
);
}
return !failed;
}
static void _log(String message) {
if (kDebugMode) debugPrint(message);
}