1
This commit is contained in:
@@ -66,41 +66,51 @@ class FeedPlayerPool {
|
||||
|
||||
/// 绑定窗口:index 为当前页;items 为已解析好播放地址的窗口数据源
|
||||
Future<void> bindWindow(int index, List<({int videoId, String url})> items) async {
|
||||
_currentIndex = index;
|
||||
// 1. 窗口内槽位按需加载(open 完才 play,libmpv 不接受未 open 的 play)
|
||||
// 1. 先把**所有**出窗/旧槽位强制停掉(不保留任何正在播放的声音)
|
||||
// 只允许窗口内 [index-1, index, index+1] 这 3 个槽位持有资源
|
||||
final activeSet = <int>{};
|
||||
for (var offset = -1; offset <= 1; offset++) {
|
||||
final i = index + offset;
|
||||
if (i >= 0 && i < items.length) activeSet.add(slotOf(i));
|
||||
}
|
||||
for (var s = 0; s < slotCount; s++) {
|
||||
if (activeSet.contains(s)) continue;
|
||||
final slot = _slots[s];
|
||||
if (slot.videoId >= 0) {
|
||||
// 确保旧视频彻底静音 + 停止解码(libmpv stop 不会立即断音 + 清缓存)
|
||||
try { await slot.player.stop(); } catch (_) {}
|
||||
slot.videoId = -1;
|
||||
slot.completeNotified = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 窗口内槽位按需加载(open 完才 play)
|
||||
for (var offset = -1; offset <= 1; offset++) {
|
||||
final i = index + offset;
|
||||
if (i < 0 || i >= items.length) continue;
|
||||
final slot = _slots[slotOf(i)];
|
||||
final item = items[i];
|
||||
if (slot.videoId == item.videoId) continue; // 已加载,避免重复 open
|
||||
if (slot.videoId == item.videoId) continue;
|
||||
slot.videoId = item.videoId;
|
||||
slot.completeNotified = false;
|
||||
if (item.url.isNotEmpty) {
|
||||
await slot.player.open(Media(item.url), play: false);
|
||||
}
|
||||
}
|
||||
// 2. 槽位状态:当前播、相邻预缓冲(保持 pause)、出窗复位
|
||||
for (var s = 0; s < slotCount; s++) {
|
||||
final slot = _slots[s];
|
||||
if (s == slotOf(index)) continue;
|
||||
if (slot.videoId == -1) continue;
|
||||
if (_inWindow(slot.videoId, index, items)) {
|
||||
slot.player.pause(); // 窗口内非当前:预缓冲不播放
|
||||
} else {
|
||||
slot.player.stop();
|
||||
slot.videoId = -1; // 出窗复位
|
||||
}
|
||||
}
|
||||
currentSlot.player.play();
|
||||
}
|
||||
|
||||
bool _inWindow(int videoId, int index, List<({int videoId, String url})> items) {
|
||||
// 3. 窗口内非当前:pause 预缓冲(但确保不出声)
|
||||
for (var offset = -1; offset <= 1; offset++) {
|
||||
final i = index + offset;
|
||||
if (i >= 0 && i < items.length && items[i].videoId == videoId) return true;
|
||||
if (i < 0 || i >= items.length) continue;
|
||||
final slot = _slots[slotOf(i)];
|
||||
if (i == index) continue; // 当前页留到最后统一 play
|
||||
try {
|
||||
slot.player.pause();
|
||||
} catch (_) {}
|
||||
}
|
||||
return false;
|
||||
|
||||
// 4. 当前槽:播放
|
||||
currentSlot.player.play();
|
||||
}
|
||||
|
||||
/// 每槽位独立订阅:≥95% 或播完触发一次 complete 回调
|
||||
|
||||
Reference in New Issue
Block a user