fix(player): 修复详情往返播放位置丢失

This commit is contained in:
Zhou Weidong committed 2026-10-22 10:27:58 +08:00
1 parent fe49c6d8b2
commit 759a02375a
16 files changed
+464 -5

No files matched your search

@@ -0,0 +1,79 @@
// Author: fruit.com.cn
const Duration _defaultMaxAge = Duration(hours: 12);
/// 进程内最近播放位置。
class CachedPlaybackPosition {
const CachedPlaybackPosition({
required this.episodeId,
required this.dramaId,
required this.position,
required this.duration,
required this.updatedAt,
});
final String episodeId;
final String dramaId;
final Duration position;
final Duration duration;
final DateTime updatedAt;
}
/// 按集缓存最近播放位置,仅当前进程有效。
class PlaybackPositionCache {
PlaybackPositionCache({
DateTime Function()? now,
this.maxAge = _defaultMaxAge,
}) : _now = now ?? DateTime.now;
final DateTime Function() _now;
final Duration maxAge;
final Map<String, CachedPlaybackPosition> _positions = {};
/// 保存最近有效播放位置;零位置不会覆盖已有记录。
void save({
required String episodeId,
required String dramaId,
required Duration position,
required Duration duration,
}) {
if (episodeId.isEmpty || dramaId.isEmpty || position <= Duration.zero) {
return;
}
_positions[episodeId] = CachedPlaybackPosition(
episodeId: episodeId,
dramaId: dramaId,
position: position,
duration: duration,
updatedAt: _now(),
);
}
/// 读取同剧同集且未过期的最近位置。
CachedPlaybackPosition? read(String episodeId, {required String dramaId}) {
final entry = _positions[episodeId];
if (!_isValid(entry, dramaId)) return null;
return entry;
}
/// 读取指定短剧最近更新的有效位置。
CachedPlaybackPosition? latestForDrama(String dramaId) {
CachedPlaybackPosition? latest;
for (final entry in _positions.values) {
if (!_isValid(entry, dramaId)) continue;
if (latest == null || !entry.updatedAt.isBefore(latest.updatedAt)) {
latest = entry;
}
}
return latest;
}
bool _isValid(CachedPlaybackPosition? entry, String dramaId) {
if (entry == null ||
entry.dramaId != dramaId ||
entry.position <= Duration.zero) {
return false;
}
return _now().difference(entry.updatedAt) <= maxAge;
}
}