This commit is contained in:
lz_db
2026-10-25 16:14:26 +08:00
parent 7fae7387f5
commit 1d9cd1f9c7
10 changed files with 288 additions and 13 deletions
+17
View File
@@ -66,6 +66,23 @@ class FeedPlayerPool {
/// open(play:false) 内部的 pause 覆盖导致恢复后不播)
Future<void>? _pendingBind;
/// 当前槽正在播放的视频(-1 表示尚未绑定)与实时播放位置
int get currentVideoId => currentSlot.videoId;
Duration get currentPosition {
try {
return currentSlot.player.state.position;
} catch (_) {
return Duration.zero;
}
}
/// 冷启动续播:指定视频从 position 起播(bindWindow 时经 mpv start 属性应用)
void setResumePoint(int videoId, Duration position) {
_resumeVideoId = videoId;
_resumePosition = position;
}
/// 初始化(创建 3 槽位并订阅各自进度流)
void init() {
for (var i = 0; i < slotCount; i++) {
@@ -0,0 +1,79 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
/// Feed 播放进度持久化:记录每个策略最后观看的视频与播放位置,
/// App 冷启动重新拉列表后按 videoId 定位,继续上次的视频。
class FeedProgress {
const FeedProgress({
required this.videoId,
required this.index,
required this.positionMs,
});
final int videoId;
final int index;
final int positionMs;
}
class FeedProgressStore {
FeedProgressStore._(this._prefs);
final SharedPreferences _prefs;
static const String _prefix = 'feed_progress_';
static const String _lastStrategyKey = 'feed_last_strategy';
static FeedProgressStore? _instance;
/// 初始化(main 启动阶段调用)
static Future<void> init() async {
_instance = FeedProgressStore._(await SharedPreferences.getInstance());
}
/// 测试注入
static void initForTest(SharedPreferences prefs) {
_instance = FeedProgressStore._(prefs);
}
static FeedProgressStore get I => _instance!;
Future<void> save(
String strategy, {
required int videoId,
required int index,
required int positionMs,
}) async {
await _prefs.setString(
'$_prefix$strategy',
jsonEncode({
'videoId': videoId,
'index': index,
'positionMs': positionMs,
}),
);
}
FeedProgress? read(String strategy) {
final raw = _prefs.getString('$_prefix$strategy');
if (raw == null) return null;
try {
final map = jsonDecode(raw) as Map<String, dynamic>;
final videoId = (map['videoId'] as num?)?.toInt() ?? 0;
if (videoId <= 0) return null;
return FeedProgress(
videoId: videoId,
index: (map['index'] as num?)?.toInt() ?? 0,
positionMs: (map['positionMs'] as num?)?.toInt() ?? 0,
);
} catch (_) {
return null;
}
}
Future<void> saveLastStrategy(String strategy) async {
await _prefs.setString(_lastStrategyKey, strategy);
}
String? readLastStrategy() => _prefs.getString(_lastStrategyKey);
}