perf(player): 限制雪碧图与海报预缓存内存并给播放位置缓存加容量上限
雪碧图解码从 2048 降到 1024、缓存从 8 张降到 3 张,避免擦洗预览驻留十几 MB 位图; 相邻集海报预缓存改用 ResizeImage 按 360/720 宽解码,不再缓存整张原图; 播放位置缓存按写入时间淘汰,最多保留 100 条,长会话不再只增不减; 观看记录详情失败日志加 kDebugMode 保护,release 下不再逐条打堆栈。
This commit is contained in:
1 parent
fb9001a02d
commit
0f777b19f2
5 files changed
+82
-14
No files matched your search
@@ -33,10 +33,15 @@ class PlaybackPositionCache {
|
||||
PlaybackPositionCache({
|
||||
DateTime Function()? now,
|
||||
this.maxAge = _defaultMaxAge,
|
||||
this.maxEntries = defaultMaxEntries,
|
||||
}) : _now = now ?? DateTime.now;
|
||||
|
||||
/// 最多保留的集数:长会话连看几十部剧也不至于让 Map 无限增长。
|
||||
static const int defaultMaxEntries = 100;
|
||||
|
||||
final DateTime Function() _now;
|
||||
final Duration maxAge;
|
||||
final int maxEntries;
|
||||
final Map<String, CachedPlaybackPosition> _positions = {};
|
||||
|
||||
/// 保存最近有效播放位置;零位置不会覆盖已有记录。
|
||||
@@ -57,6 +62,24 @@ class PlaybackPositionCache {
|
||||
duration: duration,
|
||||
updatedAt: _now(),
|
||||
);
|
||||
_evictOverflow();
|
||||
}
|
||||
|
||||
/// 超出上限时按写入时间淘汰最旧的一条,避免长会话内存只增不减。
|
||||
void _evictOverflow() {
|
||||
while (maxEntries > 0 && _positions.length > maxEntries) {
|
||||
String? oldestKey;
|
||||
DateTime? oldestAt;
|
||||
for (final entry in _positions.entries) {
|
||||
final at = entry.value.updatedAt;
|
||||
if (oldestAt == null || at.isBefore(oldestAt)) {
|
||||
oldestAt = at;
|
||||
oldestKey = entry.key;
|
||||
}
|
||||
}
|
||||
if (oldestKey == null) return;
|
||||
_positions.remove(oldestKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// 读取同剧同集且未过期的最近位置。
|
||||
|
||||
@@ -8,7 +8,8 @@ import 'package:dio/dio.dart';
|
||||
|
||||
import '../../config/app_config.dart';
|
||||
|
||||
const int spriteThumbnailDecodeMaxDimension = 2048;
|
||||
/// 雪碧图解码上限:擦洗预览只占很小一块区域,2048 会让单张位图膨胀到 16MB。
|
||||
const int spriteThumbnailDecodeMaxDimension = 1024;
|
||||
|
||||
/// VTT 资源拒绝访问,服务层据此清缓存并重试一次。
|
||||
class SpriteThumbnailForbiddenException implements Exception {
|
||||
|
||||
@@ -227,14 +227,17 @@ class WatchRecordsController extends PagedListController<WatchRecord> {
|
||||
);
|
||||
return detail;
|
||||
} catch (failure, stackTrace) {
|
||||
debugPrint(
|
||||
'[WatchRecordsController] detail failed dramaId=$dramaId '
|
||||
'${failure.runtimeType}: $failure',
|
||||
);
|
||||
debugPrintStack(
|
||||
stackTrace: stackTrace,
|
||||
label: '[WatchRecordsController] detail failed dramaId=$dramaId',
|
||||
);
|
||||
// 弱网时详情会成批失败,release 下不需要逐条打堆栈。
|
||||
if (kDebugMode) {
|
||||
debugPrint(
|
||||
'[WatchRecordsController] detail failed dramaId=$dramaId '
|
||||
'${failure.runtimeType}: $failure',
|
||||
);
|
||||
debugPrintStack(
|
||||
stackTrace: stackTrace,
|
||||
label: '[WatchRecordsController] detail failed dramaId=$dramaId',
|
||||
);
|
||||
}
|
||||
if (isDisposed) return null;
|
||||
final current = _recordIndex(dramaId);
|
||||
if (current < 0) return null;
|
||||
|
||||
Reference in new issue
Block a user