1
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user