赛事直播进行到第 80 分钟,那个进球的瞬间从观众屏幕上溜走了------弹幕里瞬间刷满"回一下"。如果系统没有时移能力,这一刻就永远过去了。这正是直播时移模块要解决的核心痛点:直播本是不可逆的单向流,但用户希望它像点播一样可以倒退、可以补看。把时移做对,电商大促的讲解片段、在线教育的重点板书、体育赛事的关键球,都能被观众随时拉回重看。

常规 HLS 的 TS 切片只负责分发、不被保存,所以天然无法回溯
理解时移要先理解它的对立面。常规直播流被切成 TS 切片通过 HLS 分发,但切片与原文件不被保存,播完即弃,因此无法回溯。时移的原理就是扭转这一点:开启时移后,TS 切片的信息与文件会被持久化保存,从而实现从直播开始到当前时间的任意回溯。技术上说,时移是在 HLS 分发链路之外多了一条"切片落盘"的旁路,观众请求回看时,播放器拉取的是已落盘的历史切片而非实时流。
配置项只有四组,但每一组都影响回看范围
时移的配置参数包含 AppName(须与推流一致,支持 * 做域名级配置)、StreamName、转码流(仅源流 / 包含转码流)、时移天数(1/3/7/15/30 天)。时移天数直接决定用户能往回翻多远:选 1 天意味着直播开始后 24 小时内的内容都可回看,选 30 天则覆盖整月。这条配置在总管理中心的运营后台完成,超级管理员掌握时移开关与天数上限的最高权限,运营管理员按场次需求下发,主播与观众没有配置权限------角色与权限的分层在这里把"谁能开回看"和"谁能看回看"清晰隔开。
这里还有两个容易漏的配置点:主播流域名如果关联了子播流域名,时移开关要在子域名里单独打开才对子域生效,配在主播流域名上不会自动继承;转码流参数如果选"包含转码流",时移回看就能覆盖转码版本,选"仅源流"则只能回看原始流。时移功能看起来只是加个参数,但功能开关的生效范围直接决定了用户到底能不能回看得到。
回看参数 lhs 的四段式格式,是时移的命门
时移播放地址在原 M3U8 地址上追加 aliyunols=on(固定必填)与 lhs 参数。lhs 参数格式为 lhs_{type}{format}{unit}_{zone}:type 是 start(播放开始)/ end(播放结束)/ vend(点播形式指定结束)/ offset(向前偏移);format 是 unix(UNIX 时间戳)/ human(年月日时分秒);unit 是 s(秒)/ ms(毫秒);zone 是 0~9 表示东 N 区(0 为 UTC,8 为中国时区),format 为 unix 时 zone 取 0。
一个最常用、也最容易被写错的例子:lhs_offset_unix_s_0=300 表示向前偏移 300 秒。观众点"回看 5 分钟前",前端拼的就是这个参数。除了 unix 时间戳,lhs 也支持 human 格式,例如 lhs_start_human_s_8=20170809200010 表示以东八区人类可读时间指定播放起点;zone 段在 human 格式下才有意义,用来标定时区,写错时区回看就会差出八小时。
offset 优先于 start,这条优先级规则写错就会回看错位
lhs 参数有明确的优先级(这是时移开发最易错的点):lhs_start 与 lhs_offset 必须指定其一,同时指定时以 lhs_offset 为准;lhs_end / lhs_vodend 可选,不指定则以直播模式播到推流结束;指定 lhs_vodend 为点播模式(一次性返回所有 ts,可用进度条前后拖动);同时指定 lhs_end 与 lhs_vodend 时以 lhs_vodend 为准。开发时若把优先级搞反,用户点"从头看"却从偏移点开始,体验就是"回看跳过了开头"。
时间线查询接口给出的是"哪里能回看"的答案
回看前最好先问清楚有效区间。时移时间线查询接口 GET http://{domain}/openapi/timeline/query?aliyunols=on&app=&stream=&format=ts&lhs_start_unix_s_0=&lhs_end_unix_s_0=&auth_key= 返回 retCode、description、content.current(当前系统时间,播放器可据此对时)、content.timeline\[\](有效时移时间段 start/end)。断流重推、网络波动可能产生多个 timeline 对象,播放器要能处理多段而非单段。鉴权失败返回 403------这也提醒时移地址同样要带鉴权串,不能因为是回看就放松。
一个工程上的坑要提前说:在"拉流触发转码"的配置下,直接播放转码流的时移并不能触发转码------系统不会为了回看去临时起一路转码。正确做法是提前播放过该转码流直播以触发转码,或把转码配置改成"推流触发"。否则用户点开"回看高清版"会直接拿到失败。
时移 + 转码、时移 + 封装,是两种标准化组合方案
时移可与转码组合:在转码流地址后加时移参数,实现"回看高清版本"。时移也可与封装组合:在封装流地址加时移参数,无需改时移配置,且封装开启时,时移切片格式与时长会跟随封装配置。这两种方案让回看既能选清晰度又能吃到低延迟封装的红利,是时移模块最常见的落地形态。
具体拼接上,时移 + 转码是在转码流地址后追加 lhs 参数,例如 StreamName_模板ID.m3u8 再接 ?aliyunols=on&lhs_offset_unix_s_0=300;时移 + 封装则是在封装流地址后追加时移参数,且无需改动时移配置,封装开启后时移切片的格式与时长会直接跟随封装配置走。两种方案都不引入新的存储链路,回看依旧指向那一份持久化的 TS 切片。从功能定位看,时移不是录制的替代品:录制产出可长期留存的文件,时移提供直播内的即时回看,两者互补------赛事直播用即时回看留住观众,电商大促用录制沉淀讲解片段做二次分发。
时移的硬限制,决定架构边界与成本
时移仅支持 M3U8 格式地址;同一主播流域名最大支持 10 万人观看,超出需提工单;配置后必须重新推流才生效,对进行中的直播不生效;主播流域名关联了子播流域名时,需在子域名单独开启时移开关;暂不支持多码率转码流的时移,意味着回看无法在清晰度之间切换,用户要么看源流、要么看指定的某路转码流,方案设计时要提前把这个限制告知产品侧,避免回看体验预期错位。这些限制直接框定了方案的容量上限,也影响成本------时移按时移写入量与回看规格计费,回看人数与天数越长,写入与存储成本越高,规划时要按业务峰值而非平均值估算。选 30 天意味着整月的 TS 切片都要落盘与回看,写入量约是 1 天档的 30 倍量级,时移天数要按真实回看需求定,而非"越长越好"。另外时移对进行中的直播不生效,上线新场次前就要把时移开关打开再推流------临时起意开时移是来不及的,这一步要写进运营 SOP。当回看并发逼近 10 万上限时,要提前提工单扩容而不是等观众报错,这是架构容量规划里必须预留的缓冲。
时移回看还是内容审核与申诉驳回的关键取证手段
当观众举报某场次出现违规内容,审核员不必等直播结束,直接在总管理中心的运营后台用中转参数把直播回拨到举报时间点,结合截帧复核画面是否属实;主播若对处置提起申诉,客服同样调取该时间段的时移回看作为证据,再决定维持还是驳回。时移让"事中取证"成为可能,审核工单的驳回因此有了可回放的事实依据,而不再依赖事后零散的截图。尤其在语聊、连麦这类强互动场景,违规往往转瞬即逝,没有时移回看,审核员基本只能靠举报瞬间的一张截图盲判,误判率与申诉率都会明显抬高。
端到端播放的一致性,由三端共用同一套时移参数保证
在总管理中心的运营后台里,时移开关、天数配置与回看数据应当和录制、审核放在同一管控面,超级管理员掌握最高权限,运营管理员按场次下发,避免时移配置散落在不同系统里难以审计。
小程序、PC 与移动端三端的时移回看,底层都指向同一份持久化的 TS 切片,差异只在播放层:小程序端用 HLS 拉流受平台约束,PC 运营后台可拖拽进度条精准定位,移动端 App 用播放器 SDK 做清晰度与回看进度同步。监控侧则要盯住时移链路的命中率与回看失败率,异常时通过日志回溯 timeline 对象与鉴权返回,风控规则对异常高频回看时段做标记------时移模块的可用性,最终要落到监控与日志这两条线上才算闭环。回看失败率一旦超过阈值,运维应在日志里优先排查 timeline 分段是否因断流重推而错乱,或鉴权串是否过期------这两类占了时移故障的大头,定位到了就能在分钟级恢复回看。