本文主要记录一类自托管媒体库(以 Octans 播放子系统为例)在 Web 与 Windows native/libmpv 播放链路上的排障方法:从创建会话、DirectPlay / HLS 分流、暂停恢复与 seek,到字幕资源、硬解回退与残留 window 清理。命令与路径已通用化,便于对照同类架构做定位。
播放链路一旦出问题,表面现象往往都是「播不了」「卡住」「字幕不对」。实际根因可能落在 Planner 决策、逻辑会话生命周期、HLS window、stream token、字幕 full cache、硬件加速回退,或客户端关闭后未释放服务端资源。下面按问题类型、链路边界和分场景步骤整理,避免一上来就盲翻日志。
背景与适用范围
本文适用于排查当前播放主链:
创建逻辑会话
→ DirectPlay(HttpFile 受控流)或 Transcode/DirectStream(HLS window)
→ 浏览器 <video> / hls.js,或 Windows Host + libmpv
→ progress / pause / resume / seek / rebase / stop
适合处理的问题类型大致如下:
| 类型 | 典型现象 |
|---|---|
| 会话创建失败 | POST /playback/sessions 报错、无 stream URL、权限拒绝 |
| 交付方式不符合预期 | 本该 DirectPlay 却进了 HLS;本该转码却没有 FFmpeg |
| HLS 控制面异常 | 暂停后仍高负载转码;resume 后位置跳变;seek 未复用已生成 segment |
| 数据面 HTTP 错误 | playlist / segment / stream 返回 403 / 404 / 410 / 507 |
| 硬件加速 | VAAPI 未启用或回退软件;codec / profile / bit depth 能力不确定 |
| 字幕 | 切字幕重建 session、长期 preparing、HTTPFILE 下浏览器原生字幕抢显、偏好意图丢失 |
| 资源残留 | 关闭播放后仍有 HLS window / ffmpeg 进程 |
| 客户端日志 | Windows Host 无预期日志、overlay 关闭后日志刷屏、Host 与服务端 session 生命周期对不上 |
需要注意的是:具体服务名、监听端口、数据目录、反向代理入口和客户端安装路径因部署而异。下文用占位符与「待确认」标出环境相关项;请按本机配置替换。
播放链路概览
职责边界
播放子系统通常把「能否播、如何播、如何受控下发、如何回收状态」从媒体详情查询和后台任务中拆出来。模块层次可以粗略理解成:
| 层次 | 职责 |
|---|---|
| 客户端(Web / Windows Host) | 展示 UI、发起会话、执行交付方式(原生 video / hls.js / libmpv)、上报进度与控制意图 |
| 播放 API / 逻辑会话 | 权限校验、创建与销毁逻辑会话、pause / resume / seek / rebase、字幕-only 切换 |
| Planner | 根据媒体事实、客户端能力与策略选择 DirectPlay / DirectStream / Transcode 等 |
| 流交付 | HttpFile 受控 Range 流,或 HLS window(playlist + segment + 可选字幕轨) |
| 转码运行时 | FFmpeg 进程、runtime slot、可选 stdin runtime pause、硬件加速与 tone mapping |
| 字幕子系统 | full cache、descriptor 状态、WebVTT / ASS / SUP 等资源形态 |
| 进度与恢复 | Progress 上报、ResumePosition |
核心原则是:服务端决策,客户端执行。客户端不应自行推断 HLS window 生命周期,也不应在本地重算应由服务端给出的字幕 delay 等控制面字段。
两个易混 ID
排查时务必区分:
- 逻辑会话 ID(logicalSessionId):一次用户播放会话的控制面身份;
pause/resume/seek/DELETE都围绕它。 - HLS window ID(hlsWindowId):某次转码输出窗口的身份;日志里「已启动 HLS session」的 SessionId 通常是 window ID,不是逻辑会话 ID。
rebase、grace miss、token 刷新后,逻辑会话可以不变,window 却会换成新的。
交付方式对照
| method | delivery | 是否启动 FFmpeg | 前端常见消费方式 |
|---|---|---|---|
| DirectPlay | HttpFile | 否 | <video> + Range 流 |
| DirectStream / Transcode | Hls | 是(copy 或 re-encode) | hls.js 或 native 侧 sidecar 字幕 + HLS 视频 |
创建会话后,若 method=DirectPlay,日志中不应出现该媒体文件对应的新 HLS window 启动记录。若 method=Transcode 且 delivery=Hls,则应看到 HLS window 启动,以及后续 playlist / segment 访问。
环境与通用入口
服务与日志
这里我们先确认后端服务是否在跑,并具备跟踪日志的能力。服务名与 unit 以实际部署为准:
sudo systemctl status <octans-service>
sudo journalctl -u <octans-service> -f
若前置有反向代理,播放入口相关的 4xx/5xx 需要同时看代理访问日志与后端应用日志。开发态前端 HMR(若使用)只影响静态资源与热更新,不能替代后端 session / HLS 日志。
Windows Host 侧可跟踪本机文件日志(路径待确认,示例):
$log = '<windows-host-log-path>\octans-windows.log'
Get-Content -LiteralPath $log -Tail 120
Get-Content -LiteralPath $log -Tail 80 -Wait
API 调用约定
下文控制面示例统一写成「已认证的 HTTP 请求」。实际环境可用网关 Cookie、Bearer token 或内部调试脚本,不要把真实 token 写进文档或工单。占位约定:
<api-base>:例如https://<domain>/api/v1或本机http://127.0.0.1:<port>/api/v1<auth>:合法认证头或 Cookie<logicalSessionId>/<hlsWindowId>/<token>:来自会话响应,勿手编
示例(创建会话骨架):
curl -sS -X POST "<api-base>/playback/sessions" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"mediaFileId":123,"clientKind":"Web","preferredDelivery":"Auto"}'
分场景排查
创建播放会话失败
先看响应,再看日志。
- 确认请求体:
mediaFileId、clientKind(如Web/Windows)、preferredDelivery(Auto/HttpFile/Hls等)是否合理。 - 权限与媒体事实:用户是否有读权限;该
MediaFile是否仍存在、路径是否可读。 - 后端关键字:
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "PlaybackSession|PlaybackHls|LogicalSessionId|forbidden|denied|not found"
- 容量熔断:若此前同一逻辑会话已触发 HLS 单 session 体积上限,后续恢复重建可能被后端拦截(见后文「HLS 缓存与容量」)。
DirectPlay 与 HLS 是否符合预期
期望 DirectPlay(HttpFile)
创建时指定或由 Planner 选出 preferredDelivery=HttpFile / DirectPlay 候选:
curl -sS -X POST "<api-base>/playback/sessions" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"mediaFileId":123,"clientKind":"Web","preferredDelivery":"HttpFile"}'
成功时响应大致应包含(字段名以实际 API 为准):
{
"data": {
"logicalSession": { "id": "<logicalSessionId>" },
"playback": {
"method": "DirectPlay",
"delivery": "HttpFile",
"stream": {
"url": "/api/v1/playback/stream/<token>"
}
}
}
}
判断:
method=DirectPlay且无新的 HLS window 启动日志 → 正常。- 若被强制进 HLS,需要回到 Planner 决策:源 codec / 容器 / 色彩与 HDR 风险 / 客户端能力是否导致 DirectPlay 被否决。
期望 HLS
curl -sS -X POST "<api-base>/playback/sessions" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"mediaFileId":123,"clientKind":"Web","preferredDelivery":"Hls"}'
成功时常见形态:
{
"data": {
"logicalSession": { "id": "<logicalSessionId>" },
"playback": {
"method": "Transcode",
"delivery": "Hls",
"stream": {
"url": "/api/v1/playback/hls/<hlsWindowId>/index.m3u8?token=<token>",
"hlsWindowId": "<hlsWindowId>",
"timeline": {
"mode": "hls",
"windowStartPositionMs": 0,
"playbackStartPositionMs": 0,
"startOffsetMs": 0
}
}
}
}
}
后端日志应出现类似:
[PlaybackHls] 已启动 HLS session。SessionId: <hlsWindowId>, LogicalSessionId: <logicalSessionId>, MediaFileId: 123, ...
若 preferredDelivery=Hls 却没有 FFmpeg / HLS 启动记录,重点查:Planner 是否改选 DirectPlay、runtime slot 是否占满、cache / 磁盘是否拒绝新 window、FFmpeg 启动是否失败。
暂停、恢复、Seek 与 Rebase
FFmpeg runtime pause(资源优化,不等于播放正确性)
部分 FFmpeg 运行时支持通过 stdin 写入 pause / resume 键(兼容常见 p / u 约定),用于暂停后降低转码负载。可先查能力接口:
curl -sS "<api-base>/playback/ffmpeg-capabilities" \
-H "Authorization: Bearer <auth>"
关注:
data.runtimeControl.canRuntimePauseTranscodingmode/pauseKey/resumeKey/probeError
预期口径(以当前实现为准,版本变更时需复核):
- 支持时:
canRuntimePauseTranscoding=true,mode 类似stdin-runtime-keys。 - 不支持或探测失败:HLS 命令可能继续带
-nostdin;暂停恢复仍走 pause grace / rebase 主链——这不是播放正确性失败,只是资源优化未启用。 - 配置关闭 runtime pause 时,即使 capability 支持,也不会启用。
日志关键字示例:RuntimePause、runtime pause、runtime resume。HLS window 启动日志中可核对 RuntimePauseEnabled 等字段。resume 写入失败时,后端应停止旧 window 并 rebase,不应把旧 window 继续交给前端。
暂停 HLS
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/pause" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"positionMs":180000,"hlsWindowId":"<hlsWindowId>"}'
预期:
- 逻辑会话状态为
Paused。 - HLS 操作结果类似
pause-grace-started:当前 window 不会立刻清空。 - 前端 hls.js 停止拉流;grace 超时后 cleanup 才停 window。
- runtime pause 启用时,日志出现 pause 键写入记录。
恢复 HLS
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/resume" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"positionMs":180000,"hlsWindowId":"<oldHlsWindowId>"}'
预期:
playbackStartPositionMs接近请求的positionMs;浏览器起播偏移看startOffsetMs;原片时间基准看windowStartPositionMs。- grace 命中:
same-window-resume,hlsWindowId不变,前端复用 source。 - grace miss:
resume-grace-miss-rebased,新 window ID,日志有新的 HLS 启动记录。
Seek
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/seek" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"positionMs":600000,"hlsWindowId":"<currentHlsWindowId>"}'
预期:
- cache hit:
seek-cache-hit,window 不变。 - cache miss:
seek-cache-miss-rebased,新 window。 generatedRange使用原片时间线,只表示视频 segment 可服务范围,不表示字幕缓存范围。
Rebase
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/rebase" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"positionMs":600000,"reason":"window-stale","hlsWindowId":"<currentHlsWindowId>"}'
reason 常见值:
seek / resume / window-stale / segment-missing / hls-fatal-error / token-refresh
普通用户拖进度应走 /seek。/rebase 用于 fatal error、token 刷新、window stale、segment missing 或显式强制重建。
数据面:Stream / Playlist / Segment
HTTP Stream(DirectPlay)
从创建会话响应取 playback.stream.url:
curl -i -H "Range: bytes=0-1023" \
"<api-base>/playback/stream/<token>"
预期:
- 正常 Range →
206 Partial Content - token 过期 →
410 - 权限或文件版本不匹配 →
403
HLS Playlist
curl -i "<api-base>/playback/hls/<hlsWindowId>/index.m3u8?token=<token>"
预期:
- playlist 内 segment URL 携带同一 token。
- token 内
logicalSessionId与hlsWindowId必须匹配当前 window。 - window 被替换后,旧 FFmpeg 会停;旧输出目录可能短暂进入 retiring grace。grace 结束或已清理后,旧 playlist / segment 返回
410(如HLS_WINDOW_STALE)。前端应走 resume / seek / rebase,不要死磕旧 window。
字幕相关
只切字幕,不重建主视频
# 切换
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/subtitle" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"subtitleTrackId":155492,"positionMs":600000,"hlsWindowId":"<hlsWindowId>"}'
# 关闭字幕
curl -sS -X POST "<api-base>/playback/sessions/<logicalSessionId>/subtitle" \
-H "Authorization: Bearer <auth>" \
-H "Content-Type: application/json" \
-d '{"subtitleTrackId":null,"positionMs":600000,"hlsWindowId":"<hlsWindowId>"}'
预期:
- 逻辑会话 ID 不变。
- HLS window 未失效时
hlsWindowId不变,不应出现新的「已启动 HLS session」。 - HTTPFILE 下 stream URL 不应因字幕切换重签。
subtitle.status=ready时带可请求资源;preparing时带retryAfterMs,前端应短轮询字幕-only API,不要重建主视频;failed/unsupported/unavailable应回滚到切换前状态。
偏好意图与请求边界
Web 直接播放时,session create / recreate / 字幕切换请求体一般只带最终的 selection.subtitleTrackId / audioTrackId(或 null),不应把前端内部的 subtitleSelectionSource、subtitleLanguageCodes 完整偏好对象原样打到服务端。服务端只消费最终轨 ID。
音轨默认偏好常为「自动 + 优先原始语言」:应优先命中作品原语言主轨,而不是容器里的 isDefault 外语轨;自动选择应排除评论轨 / 视障音轨。详情页手动选轨后,若起播上下文未带「手动」语义,播放页可能按 auto 重算,表现为「详情页选了 A、起播变成 B」。
Windows native 侧可在 Host 日志中检索 bridge 解析与偏好 resolve 关键字(路径待确认):
Select-String -LiteralPath '<windows-host-log-path>\octans-windows.log' `
-Pattern 'Bridge playback selection payload parsed|Playback subtitle preference resolved|Playback audio preference resolved|player.planChanged'
判断原则(实现细节以版本为准):
- bridge 解析应能区分 auto / manual / manual-off 等 source。
- 手动字幕切到无字幕版本时,应保留语言意图,resolved track 可为 null。
- 用户显式关字幕应落到 manual-off 一类结果。
player.planChanged需携带足够的 client selection metadata,否则 overlay 无法区分「无可用字幕」与「用户关闭字幕」。
字幕资源 HTTP
HLS WebVTT 路径(仅 Web/hls.js 的 hls-webvtt 呈现;native/libmpv 通常不走这条产品路径):
curl -i "<api-base>/playback/hls/<hlsWindowId>/subtitles/<subtitleTrackId>/playlist.m3u8?token=<token>"
curl -i "<api-base>/playback/hls/<hlsWindowId>/subtitles/<subtitleTrackId>/segments/<startMs>.vtt?token=<token>"
重点看响应头 X-Octans-Subtitle-Status(或等价字段):full-cache-hit / ready / generated / empty / failed 等。
独立字幕资源(HTTPFILE / sidecar):
curl -i "<api-base>/playback/subtitles/<logicalSessionId>/<subtitleTrackId>/track.vtt?token=<token>"
curl -i "<api-base>/playback/subtitles/<logicalSessionId>/<subtitleTrackId>/track.raw.vtt?token=<token>"
curl -i "<api-base>/playback/subtitles/<logicalSessionId>/<subtitleTrackId>/track.ass?token=<token>"
curl -i "<api-base>/playback/subtitles/<logicalSessionId>/<subtitleTrackId>/track.sup?token=<token>"
说明:
- full cache 未就绪时误请求 track,预期快速
425+ preparing 类状态,不应出现约 60 秒的长 pending。 - PGS / SUP 一般不做 OCR、不转 WebVTT、不烧录进视频;排查漏显 / 晚显时先确认 descriptor 是否 ready,再核对
rendererOffsetMs、windowStartPositionMs与播放器当前时间是否一致。 - native HLS 字幕常见为 sidecar 完整文件 + 服务端给出的 delay(与 window 起点相关)。客户端应消费服务端返回值,不要在本地重新推导;若非零
windowStartPositionMs下客户端 delay 仍为 0,字幕会从影片 0 点开始显示。 - HTTPFILE + 客户端声明原生内嵌字幕能力时,可走 in-band 选轨,服务端不应为此次播放再抽一遍文本字幕。HLS 主输出通常没有字幕流,即使客户端声明 native tracks,也不应误判为 in-band。
HTTPFILE 下浏览器原生字幕抢显
可在浏览器控制台检查 <video> 的 textTracks,确认非业务托管的 in-band track 保持 disabled,仅托管 track 可为 showing。若浏览器拒绝关闭 in-band track,该样本不宜作为可靠 HTTPFILE 字幕路径,应改走 HLS / remux。
ASS 被 OSD 顶高
播放中无 hover / 焦点 / 菜单时,控制条 OSD 应自动隐藏,ASS 底部偏移回到默认值;菜单打开时不应提前隐藏。可用页面布局节点上的 CSS 变量与 dataset 核对(具体 class 名以当前前端为准)。
硬解 / VAAPI 回退
创建 HLS 会话后查后端日志:
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "已启动 HLS session|TranscodeAcceleration|HardwareProvider|h264_vaapi|hevc_vaapi|VAAPI"
成功使用 VAAPI 的信号示例:
VideoMode: h264-vaapi 或 h265-vaapi
TranscodeAcceleration: vaapi
HardwareProvider: vaapi
HardwareDevice: /dev/dri/renderD128
HardwareFallbackReason: (null)
FFmpeg 中出现类似「No quality level set; using default」通常不是失败,表示 encoder 使用默认质量。
若看到 vaapi-fallback-software 及 HardwareFallbackReason,继续检查:
ls -l /dev/dri
id <service-user>
sudo journalctl -u <octans-service> --since "30 min ago" \
| rg "VAAPI|vaapi|fallback|ffmpeg"
需要区分两类问题:
- 运行时有没有启用 VAAPI / 是否权限与设备节点问题。
- 该源 codec / profile / bit depth 在某代 GPU 上是否具备固定功能硬解硬编——这属于硬件能力矩阵,不等于业务 Planner 已经接入的路线。业务当前支持范围以项目的转码支持矩阵为准(版本变更时需复核)。
停止播放与残留 HLS window
正常停止:
curl -sS -o /dev/null -w "%{http_code}\n" -X DELETE \
"<api-base>/playback/sessions/<logicalSessionId>" \
-H "Authorization: Bearer <auth>"
预期:
- 返回
204。 - 当前 HLS window 停止并清理输出目录。
- 再次停止同一逻辑会话不应变成用户可见错误。
- HLS 数据面独立 DELETE 入口若已下线,不要再调。
Windows native 直接关客户端时,也必须先释放服务端逻辑会话。排查转码残留时两侧一起看:
Select-String -LiteralPath '<windows-host-log-path>\octans-windows.log' `
-Pattern 'DELETE .*playback/sessions|Timed out while stopping playback|Timed out while stopping libmpv'
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "logical session 已停止并释放|ffmpeg 进程退出|slot lease 已释放|inactive-timeout"
若客户端只有本地进程退出,没有 DELETE .../playback/sessions/{id},服务端会把 HLS window 继续视为被引用,直到 inactive timeout 兜底(默认量级常为数分钟到一刻钟级,具体配置项如 Playback:Hls:InactiveSessionTimeoutSeconds 以环境为准)。兜底只释放 window / ffmpeg / runtime slot,不等同于正常 logical session stop。
overlay 关闭后日志刷屏
若 play.stop 已完成、服务端 DELETE 已 204,之后仍每秒只有 overlay commandResult 一类心跳,常见原因是隐藏 overlay 仍在发 shortcut context heartbeat。优先查前端 overlay 关闭 cleanup,而不是 libmpv 字幕或 delay 失败。
HLS 缓存与容量
容量相关日志关键字:HLS cache、preflight、cleanup、HLS_SESSION_SIZE、HLS_CACHE、HLS_INSUFFICIENT。
重点字段含义(日志字段名以实际为准):
| 概念 | 含义 |
|---|---|
| Reason | 清理入口:startup-scan / runtime-loop / preflight-cleanup 等 |
| Trigger | 触发原因:expired-orphan / soft-watermark / hard-limit / min-free-disk 等 |
| Bytes* / CacheBytes / FreeDiskBytes | 释放量与水位 |
| 容量熔断 | 单 session 超限后可能阻断同一 logical session 的后续重建 |
常见错误码口径:
HLS_CACHE_LIMIT_EXCEEDED/HLS_INSUFFICIENT_DISK:新建 window 前已尝试 cleanup,全局 cache 或磁盘仍不健康;前端不应无限重试。HLS_SESSION_SIZE_EXCEEDED:当前 session 目录超限且 cleanup 无法恢复;后端停止 window 并可能阻断恢复重建;应展示容量错误而不是继续 rebase。
验证命令速查
服务端日志切片
# 逻辑会话与 HLS
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "PlaybackSession|PlaybackHls|LogicalSessionId"
# FFmpeg / 硬解
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "ffmpeg <hlsWindowId>|h264_vaapi|hevc_vaapi|error|failed|fallback"
# 数据面
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "playlist|segment|TokenExpired|HLS session|HLS_WINDOW_STALE"
# 字幕
sudo journalctl -u <octans-service> --since "10 min ago" \
| rg "PlaybackSubtitle|SubtitleTrackId|batch cache|full cache|字幕"
# 容量
sudo journalctl -u <octans-service> --since "30 min ago" \
| rg "HLS cache|preflight|cleanup|HLS_SESSION_SIZE|HLS_CACHE|HLS_INSUFFICIENT"
Windows Host 关键字(可选)
Select-String -LiteralPath '<windows-host-log-path>\octans-windows.log' `
-Pattern 'play.open|play.selection.set|play.quality.set|play.stop|playback.close|player.stateChanged|player.planChanged|player.error|PlaybackSessionService|LibMpvBackend|fail:|crit:|warn:'
播放设置变更通常只影响下一次 play.open,不热改当前 mpv session,也不要求重启客户端(以当前产品行为为准)。
创建会话响应核对清单
| 检查项 | 预期 |
|---|---|
| DirectPlay | 无新 HLS window;stream 为 Range URL |
| HLS | 有 hlsWindowId;playlist URL 带 token;timeline 字段齐全 |
| 字幕 preparing | 无过早可挂载 URL;后台轮询至 ready |
| 停止 | DELETE 204;ffmpeg 退出;无长期残留 window |
常见结论速查
| 现象 | 结论 / 处理 |
|---|---|
| DirectPlay 后无 FFmpeg 日志 | 正常。DirectPlay 不走 FFmpeg。 |
pause grace 超时后旧 playlist/segment 410 | 正常。旧 window 已停;前端应 resume 或 rebase。 |
grace 内恢复 hlsWindowId 不变 | 正常。same-window resume。 |
恢复后出现新 hlsWindowId | 正常。grace miss 或 window 不可用,已重建。 |
| HLS 数据面 DELETE 不存在 | 正常。stop 收敛到逻辑会话 DELETE。 |
token 过期 410 | 正常。刷新 DirectPlay stream 或 rebase HLS。 |
| VAAPI 默认 quality level 日志 | 正常,不代表回退。 |
Ignored stale subtitle appearance 类日志 | 通常正常:多 WebView 重放旧外观偏好被按时间戳丢弃;仅当新调整也被忽略或伴随 command error 时再查。 |
| 画面 fit mode 应用成功日志 | 正常写入 presentation;不代表选轨或 HLS 重建。 |
| fit mode 失败 / command timeout | 查 command payload 与 libmpv property;该链路不应触发选轨或 recreate。 |
| 缓存/磁盘类错误码 | 勿无限重试;先清理磁盘与 cache 策略。 |
| 单 session 体积超限 | 勿继续 rebase;向用户展示容量错误。 |
注意事项
- 不要编造 window ID 与 token。一律从最新会话响应读取;window 替换后旧 token 立即失效。
- 区分优化与正确性。runtime pause 未启用不等于 seek/resume 错误;inactive timeout 兜底不等于正常 stop。
- 字幕 full cache 与视频 segment 范围无关。seek cache hit 不保证字幕已缓存完毕。
- 生产环境操作。重启转码服务、清理 HLS 缓存目录会影响正在观看的用户;变更前确认影响范围。
- 路径与服务名。本文中的 unit 名、数据目录、Windows 日志路径、代理入口均为占位;不同私有化部署需要替换。
- 能力矩阵与业务接入。GPU 厂商公开硬解能力 ≠ 当前 Planner / FFmpeg 命令已接线;不确定时写「待确认」并对照版本发布说明。
- 敏感信息。工单与文档中使用
<token>、<domain>、<auth>等占位符,避免粘贴完整 Authorization 头与内网地址。
相关阅读
同系列还可对照:
- Octans Android 播放内核演进:从 libmpv 单内核到双内核实验:客户端默认内核、实验通道与能力边界。
- 媒体内容产品 + 管理后台混合前端的 UI 基座选型:Web 播放页 overlay 与自有 UI 边界,和播放控制面解耦。
来源
本文改写自 Octans 项目文档中的播放调试用法说明(octans-docs usage 层),并吸收播放架构文档中的职责边界描述。命令与路径已做通用化与脱敏,不绑定特定内网环境;接口字段以目标环境当前 API 为准。