fix(player): 观看全集复用抓帧首屏

This commit is contained in:
Zhou Weidong committed 2026-10-26 17:20:24 +08:00
1 parent 4d3d067f77
commit 55fc2796a9
4 files changed
+136 -36

No files matched your search

@@ -0,0 +1,63 @@
// Author: fruit.com.cn
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class PlayerFrameCapture {
const PlayerFrameCapture._();
static const int budgetMilliseconds = 32;
static Future<Uint8List?> capture({
required BuildContext context,
required GlobalKey boundaryKey,
required String source,
}) async {
final boundary = boundaryKey.currentContext?.findRenderObject();
if (boundary is! RenderRepaintBoundary) {
_log('[player-entry] phase=frame-capture-unavailable source=$source');
return null;
}
final stopwatch = Stopwatch()..start();
try {
final pixelRatio = MediaQuery.devicePixelRatioOf(
context,
).clamp(1.0, 2.0).toDouble();
final image = await boundary.toImage(pixelRatio: pixelRatio);
final data = await image.toByteData(format: ui.ImageByteFormat.png);
image.dispose();
if (stopwatch.elapsedMilliseconds > budgetMilliseconds) {
_log(
'[player-entry] phase=frame-capture-over-budget source=$source '
'ms=${stopwatch.elapsedMilliseconds} budget_ms=$budgetMilliseconds',
);
}
if (data == null) {
_log('[player-entry] phase=frame-capture-empty source=$source');
return null;
}
final bytes = data.buffer.asUint8List(
data.offsetInBytes,
data.lengthInBytes,
);
_log(
'[player-entry] phase=frame-captured source=$source '
'bytes=${bytes.length} ms=${stopwatch.elapsedMilliseconds}',
);
return bytes;
} catch (error) {
_log(
'[player-entry] phase=frame-capture-failed source=$source '
'error=$error',
);
return null;
}
}
static void _log(String message) {
if (kDebugMode) debugPrint(message);
}
}