内置 Web 播放器:点击"距当前 5 小时内的历史节目"会跳到直播画面,而不是从节目开始播放
问题描述(Problem)
内置 Web 播放器(/player)的 EPG 节目单中,点击距当前时刻 5 小时以内的"已结束"节目时,画面会跳到当前直播(≈当前时刻),而不是从节目开始时间播放。而点击 5 小时以前(如昨天)的节目则能正确从节目开始播放。
(In the built-in web player's EPG, clicking a finished program within the last 5 hours jumps to the live edge (current time) instead of starting from the program's start time. Programs older than 5 hours (e.g. yesterday) start correctly from the beginning.)
复现步骤(Steps to Reproduce)
- 配置带时移回看的 M3U(频道带
catchup + catchup-source,如 &playseek={utc:YmdHMS}-{utcend:YmdHMS})
- 打开
http://<host>:5140/player,进入某频道
- 打开 EPG 节目单,点击**今天"3 小时前已结束"**的某个节目(例如 12:00 测试时点击 8:55 的节目)
- 观察:画面时钟显示接近当前时刻(像直播),不是所点击节目的开始时间
预期行为(Expected)
点击任何已结束的节目,都应从该节目的开始时间播放(与点击昨天/更早的节目行为一致)。
实际行为(Actual)
- 距当前 > 5 小时的节目:点击后从节目开始播放 ✅
- 距当前 ≤ 5 小时的已结束节目:点击后跳到当前时刻(直播边缘) ❌(画面像直播,需手动把进度条拖回开头)
实测数据(约 12:00 测试):6:30(5.5h 前)能从头播;7:00(5h 前)能播;8:55(3h 前)跳直播。分界正好 5 小时。
环境(Environment)
- rtp2httpd 版本:3.15.3-r1(OpenWrt luci 安装;GitHub main 分支代码已对照,行为相同)
- 播放器:内置 Web 播放器
/player
- 上游:电信 IPTV(HLS 单播 + playseek 时移),平台按本地时间解释 playseek
- 浏览器:Chrome/Edge
技术分析(可能的根因,供参考)
排查源码(web-ui/src/lib/m3u-parser.ts 的 buildCatchupSegments):
const segmentDurationMs = Math.min(
Math.max(now.getTime() - startTime.getTime(), CATCHUP_MIN_DURATION_MS),
5 * 60 * 60 * 1000, // max 5 hours
);
// Build segments from startTime to now
let currentTime = new Date(startTime.getTime());
const splitPoint = new Date(now.getTime() - 10000);
while (currentTime < splitPoint) {
const segmentEndTime = new Date(Math.min(currentTime.getTime() + segmentDurationMs, splitPoint.getTime()));
segments.push({ duration: ..., url: buildCatchupUrl(currentTime, segmentEndTime) });
...
}
- 当
now - startTime ≤ 5h 时,只生成单个分段 [节目开始, now-10s];
- 播放核心(
playback-engine/mse/playback-controller.ts)对单个分段似乎从**分段末尾(=当前时刻/live edge)**开始播放;
- 当
now - startTime > 5h 时生成多个分段,播放器从第一分段开头播放,所以正常。
也就是说:单个分段的结束时间等于当前时刻,播放器把它当作"进行中的直播缓冲",初始播放位置落在末尾(当前时刻)。
期望改进方向:
- 单分段时也从分段开头(节目开始时间)播放;或
- 对
isPast(节目已结束)的节目,用节目结束时间作为分段结束(而不是当前时刻);或
- 至少对"已结束"的节目统一从头播放。
相关文件(Related Files)
web-ui/src/lib/m3u-parser.ts — buildCatchupSegments(分段逻辑,5h 上限)
web-ui/src/pages/player.tsx — handleProgramSelect / handleVideoSeek
web-ui/src/playback-engine/mse/playback-controller.ts — 分段初始播放位置
内置 Web 播放器:点击"距当前 5 小时内的历史节目"会跳到直播画面,而不是从节目开始播放
问题描述(Problem)
内置 Web 播放器(
/player)的 EPG 节目单中,点击距当前时刻 5 小时以内的"已结束"节目时,画面会跳到当前直播(≈当前时刻),而不是从节目开始时间播放。而点击 5 小时以前(如昨天)的节目则能正确从节目开始播放。(In the built-in web player's EPG, clicking a finished program within the last 5 hours jumps to the live edge (current time) instead of starting from the program's start time. Programs older than 5 hours (e.g. yesterday) start correctly from the beginning.)
复现步骤(Steps to Reproduce)
catchup+catchup-source,如&playseek={utc:YmdHMS}-{utcend:YmdHMS})http://<host>:5140/player,进入某频道预期行为(Expected)
点击任何已结束的节目,都应从该节目的开始时间播放(与点击昨天/更早的节目行为一致)。
实际行为(Actual)
实测数据(约 12:00 测试):6:30(5.5h 前)能从头播;7:00(5h 前)能播;8:55(3h 前)跳直播。分界正好 5 小时。
环境(Environment)
/player技术分析(可能的根因,供参考)
排查源码(
web-ui/src/lib/m3u-parser.ts的buildCatchupSegments):now - startTime ≤ 5h时,只生成单个分段[节目开始, now-10s];playback-engine/mse/playback-controller.ts)对单个分段似乎从**分段末尾(=当前时刻/live edge)**开始播放;now - startTime > 5h时生成多个分段,播放器从第一分段开头播放,所以正常。也就是说:单个分段的结束时间等于当前时刻,播放器把它当作"进行中的直播缓冲",初始播放位置落在末尾(当前时刻)。
期望改进方向:
isPast(节目已结束)的节目,用节目结束时间作为分段结束(而不是当前时刻);或相关文件(Related Files)
web-ui/src/lib/m3u-parser.ts—buildCatchupSegments(分段逻辑,5h 上限)web-ui/src/pages/player.tsx—handleProgramSelect/handleVideoSeekweb-ui/src/playback-engine/mse/playback-controller.ts— 分段初始播放位置