本文主要记录一类自托管媒体库(以 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 却会换成新的。

交付方式对照

methoddelivery是否启动 FFmpeg前端常见消费方式
DirectPlayHttpFile<video> + Range 流
DirectStream / TranscodeHls是(copy 或 re-encode)hls.js 或 native 侧 sidecar 字幕 + HLS 视频

创建会话后,若 method=DirectPlay,日志中不应出现该媒体文件对应的新 HLS window 启动记录。若 method=Transcodedelivery=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"}'

分场景排查

创建播放会话失败

先看响应,再看日志。

  1. 确认请求体:mediaFileIdclientKind(如 Web / Windows)、preferredDeliveryAuto / HttpFile / Hls 等)是否合理。
  2. 权限与媒体事实:用户是否有读权限;该 MediaFile 是否仍存在、路径是否可读。
  3. 后端关键字:
sudo journalctl -u <octans-service> --since "10 min ago" \
  | rg "PlaybackSession|PlaybackHls|LogicalSessionId|forbidden|denied|not found"
  1. 容量熔断:若此前同一逻辑会话已触发 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.canRuntimePauseTranscoding
  • mode / pauseKey / resumeKey / probeError

预期口径(以当前实现为准,版本变更时需复核):

  • 支持时:canRuntimePauseTranscoding=true,mode 类似 stdin-runtime-keys
  • 不支持或探测失败:HLS 命令可能继续带 -nostdin;暂停恢复仍走 pause grace / rebase 主链——这不是播放正确性失败,只是资源优化未启用。
  • 配置关闭 runtime pause 时,即使 capability 支持,也不会启用。

日志关键字示例:RuntimePauseruntime pauseruntime 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-resumehlsWindowId 不变,前端复用 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 内 logicalSessionIdhlsWindowId 必须匹配当前 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),不应把前端内部的 subtitleSelectionSourcesubtitleLanguageCodes 完整偏好对象原样打到服务端。服务端只消费最终轨 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,再核对 rendererOffsetMswindowStartPositionMs 与播放器当前时间是否一致。
  • 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-softwareHardwareFallbackReason,继续检查:

ls -l /dev/dri
id <service-user>
sudo journalctl -u <octans-service> --since "30 min ago" \
  | rg "VAAPI|vaapi|fallback|ffmpeg"

需要区分两类问题:

  1. 运行时有没有启用 VAAPI / 是否权限与设备节点问题。
  2. 该源 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 cachepreflightcleanupHLS_SESSION_SIZEHLS_CACHEHLS_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;向用户展示容量错误。

注意事项

  1. 不要编造 window ID 与 token。一律从最新会话响应读取;window 替换后旧 token 立即失效。
  2. 区分优化与正确性。runtime pause 未启用不等于 seek/resume 错误;inactive timeout 兜底不等于正常 stop。
  3. 字幕 full cache 与视频 segment 范围无关。seek cache hit 不保证字幕已缓存完毕。
  4. 生产环境操作。重启转码服务、清理 HLS 缓存目录会影响正在观看的用户;变更前确认影响范围。
  5. 路径与服务名。本文中的 unit 名、数据目录、Windows 日志路径、代理入口均为占位;不同私有化部署需要替换。
  6. 能力矩阵与业务接入。GPU 厂商公开硬解能力 ≠ 当前 Planner / FFmpeg 命令已接线;不确定时写「待确认」并对照版本发布说明。
  7. 敏感信息。工单与文档中使用 <token><domain><auth> 等占位符,避免粘贴完整 Authorization 头与内网地址。

相关阅读

同系列还可对照:

来源

本文改写自 Octans 项目文档中的播放调试用法说明(octans-docs usage 层),并吸收播放架构文档中的职责边界描述。命令与路径已做通用化与脱敏,不绑定特定内网环境;接口字段以目标环境当前 API 为准。