跳转到正文

DAG 管道

rust-srec 使用 有向无环图(DAG) 系统进行后处理工作流。

什么是 DAG 管道?

DAG 管道定义一系列带依赖关系的处理步骤。步骤在可能时并行执行,但遵循依赖顺序。

管道触发器 (Pipeline Triggers)

rust-srec 的强大之处在于其自动化的触发机制。您可以根据需求在不同阶段触发管道:

1. 分段管道 (Segment Pipeline)

  • 触发时机:单个视频分段(.flv, .ts)或弹幕文件(.xml, .json)下载完成后。
  • 典型用途:转封装(Remux)、视频截图、弹幕格式转换。
  • 输入:单个文件。

2. 配对分段管道 (Paired Segment Pipeline)

  • 触发时机:当同一分段的 视频文件弹幕文件 都准备好,并且相关分段处理结束后。
  • 典型用途:将弹幕烧录进视频(Burn-in)、合并分段信息。
  • 输入:对应的视频文件 + 弹幕文件。

3. 会话完成管道 (Session Complete Pipeline)

  • 触发时机:整个直播会话结束,最终录制文件已可用,并且该会话所有前期的分段或配对处理都已结束。
  • 典型用途:全会话合并、上传到云盘(如 Rclone 到 Google Drive/OneDrive)、发送最终完成通知。
  • 输入:该会话产生的所有最终产物列表。

稳定性说明

如果弹幕先于最终视频文件完成,rust-srec 会等待视频文件准备好后再启动会话完成管道。这样可以避免合并、上传或清理等最终任务在缺少视频输入时过早运行。

内置处理器 (Processors)

每个管道步骤由一个专门的处理器执行:

处理器 ID功能核心参数
remux更改容器格式,也可选择重新编码format, video_codec, audio_codec
danmaku_factory弹幕转换output_format (ass)
ass_burnin将字幕硬烧录进视频处理器预设配置
thumbnail从视频中提取画面作为图片timestamp_secs, width, quality, preserve_resolution
audio_extract提取音轨format, bitrate, sample_rate
compression视频转码编解码器与质量设置
rclone云端同步destination_root, operation, time_anchor, args
baidupcs通过 BaiduPCS-Go 上传到百度网盘destination_root, policy, norapid, time_anchor, args
copy_move复制或移动本地文件目标路径与操作设置
metadata写入元数据(nfo, json)-
delete自动清理中间文件-
execute执行自定义 Shell 脚本command, scan_output_dir, scan_extension

execute 命令中的 {input}{output}{streamer}{title} 等占位符,其取值会自动加引号后再交给 Shell,因此包含空格、引号、$; 的路径和标题都会以纯文本形式传入。转义方式会跟随占位符所处的位置:直接作为参数、位于 '...'"..." 中、位于 $(...) 或反引号中、位于 $(( ... )) 中,以及位于 here-document 正文中。占位符按原样书写即可(加不加引号都行),不需要自己再做转义。命令的其余部分不受影响,管道符、&& 和重定向照常可用。

有两点限制需要注意。如果某个取值中单独一行正好是所在 here-document 的结束标记,会提前结束该 here-document,此时步骤会带着提示信息失败——请选用不会在路径中出现的结束标记。另外在 Windows 上,cmd 会在命令执行前展开取值中出现的 %VAR%,而它没有提供任何转义方式。

百度网盘(baidupcs

baidupcs 处理器通过外部 BaiduPCS-Go 命令行工具将录像上传到百度网盘(Docker 镜像已内置;裸机部署需自行安装,若不在 PATH 中可通过 BAIDUPCS_PATH 指定路径)。

  • 登录:在网页端打开任意 baidupcs 预设,通过账号卡片粘贴 Cookie 字符串(推荐)或 BDUSS + STOKEN 登录。凭据交给 BaiduPCS-Go 处理,登录会话保存在它的配置目录(BAIDUPCS_GO_CONFIG_DIR)中;卡片同时显示当前账号和网盘容量。勾选记住凭据以便自动重新登录后,凭据也会保存在服务器上(明文,与平台 Cookie 相同):登录会话过期时,上传任务会在首次尝试前检查登录状态、并在重试前再补一次登录,无需人工干预。如果重放的登录被拒绝(通常是修改密码导致会话令牌失效),会发出高优先级的 baidupcs_relogin_failed 通知,并在一小时内暂停后续尝试——失效凭据只产生一条提醒,而不是每个任务都白白请求一次百度。退出登录会一并清除保存的凭据。
  • 目标路径destination_root 支持 {streamer}{title} 及时间占位符,始终解析为网盘的绝对路径。不存在的文件夹会在上传时自动创建。
  • 重试:BaiduPCS-Go 的退出码无法反映上传结果,rust-srec 会解析其逐文件输出来判定成败。无论是运行内重试还是手动重试任务,都只会重新上传尚未确认结果的文件;配合默认的 skip 策略和秒传检测,部分失败后的重试开销很小。
  • 限制:单文件超过 128 GB 会被百度拒绝;传输中断后只能从头重传(BaiduPCS-Go v4 已不支持断点续传)。由于该工具的本地状态存储不支持并发写入,上传任务同一时间只运行一个 BaiduPCS-Go 进程;任务运行期间也请勿手动对同一配置目录执行 BaiduPCS-Go 命令。

预设系统 (Presets)

为了提高效率,系统提供了两种预设:

  • Job Preset (任务预设):针对单个步骤的配置模板(如“1080p 封面提取”)。
  • Pipeline Preset (管道预设):完整的 DAG 工作流定义(如“B站标准录制流程”)。

数据路由

依赖关系同时决定一个步骤何时可以运行以及会收到哪些文件路径

  1. 每个根步骤(没有依赖的步骤)都会收到管道触发器提供的原始输入列表。
  2. 非根步骤会等待其所有直接依赖完成。
  3. 该步骤的输入是所有直接依赖的输出列表,按 depends_on 顺序合并并去重。
  4. 系统不会自动继承间接祖先步骤的输出。

对于 A -> B -> C 这样的链,步骤 C 只会收到 B 报告的输出,不会同时收到 A 的输出。这样可以防止已被替换、已被删除或无关的中间文件流入后续步骤。

处理器的输出语义同样重要:

  • remuxcompression 等转换处理器输出转换后的文件。
  • thumbnailaudio_extract 等衍生文件处理器只输出新生成的衍生文件,不会透传源文件。
  • rclonecopysync 会透传本地输入路径;rclonemove 会消耗本地文件,因此没有本地输出。
  • baidupcs 会透传本地输入路径;若开启了“上传后删除本地文件”,被删除的文件不会出现在输出中。
  • delete 没有输出。

因此,线性的 remux -> thumbnail -> rclone 图只会把缩略图发送给 rclone。若要同时上传转封装后的视频及其缩略图,需要把两个产出步骤都直接连接到 rclone

在这个图中,rclone 仍然会等待 thumbnail,因为 remuxthumbnail 都是它的直接依赖。额外的 remux -> rclone 边只负责传递视频,不会让上传提前开始。

高级特性

任务并行与依赖 (Fan-in / Fan-out)

  • 扇出(Fan-out):一个步骤将输出路由给多个下游步骤。只有在其他依赖和 Worker 容量也允许时,这些下游步骤才可能并发运行。
  • 扇入(Fan-in):一个步骤具有多个直接依赖。它会等待所有依赖完成,并接收这些依赖合并后的输出。

扇出描述的是图中的数据路由,不保证步骤一定同时执行。

自动清理

delete 步骤删除的是其所依赖步骤产出的文件,而不是原始录制文件。在 upload 步骤之后使用是安全的(rclone 复制会把已上传的文件作为输出透传),因此添加一个 depends_on: uploaddelete 步骤即可实现“上传成功后删除本地副本”。

不要remux/转码步骤之后放置 delete 步骤:它会删除转码后的结果文件,因为那正是转码步骤的产出。若要在转码后删除原始源文件,请改为在转码步骤上启用 Remove Input on Successremove_input_on_success)。

性能建议

重编码(如 ass_burnin)是极其消耗 CPU 的。建议在 cpu_pool 中限制较小的并发数,以防止系统负载过高影响下载稳定性。

核心概念

步骤

每个步骤执行一项处理任务:

步骤类型说明
remux转换容器格式(例如 FLV -> MP4)
thumbnail提取缩略图
rclone上传到云存储
delete删除其直接依赖步骤产出的文件
preset使用命名的任务预设运行一个步骤
workflow将命名的管道预设展开为子 DAG
inline使用 DAG 中内嵌的配置运行处理器

依赖关系

步骤可以依赖其他步骤:

  • 扇出:一个步骤是多个下游步骤的直接依赖。
  • 扇入:一个步骤等待多个直接依赖,并合并它们的输出。

执行状态

DAG 定义

json
{
  "name": "Post-Process",
  "steps": [
    {
      "id": "remux",
      "step": {"type": "preset", "name": "remux"},
      "depends_on": []
    },
    {
      "id": "thumbnail",
      "step": {"type": "preset", "name": "thumbnail"},
      "depends_on": ["remux"]
    },
    {
      "id": "upload",
      "step": {"type": "preset", "name": "upload"},
      "depends_on": ["remux", "thumbnail"]
    },
    {
      "id": "cleanup",
      "step": {"type": "preset", "name": "delete_source"},
      "depends_on": ["upload"]
    }
  ]
}

步骤也可以直接使用内联处理器,而不是引用任务预设:

json
{
  "id": "thumbnail",
  "step": {
    "type": "inline",
    "processor": "thumbnail",
    "config": {
      "timestamp_secs": 10,
      "width": 640,
      "quality": 2
    }
  },
  "depends_on": ["remux"]
}

管道预设

可以将 DAG 定义保存为可复用的预设:

  1. 通过 API 或 UI 创建预设。
  2. 将预设分配给主播或模板。
  3. 录制完成后自动运行预设。

错误处理

  • 快速失败(Fail-fast):某个步骤失败时,取消尚未执行的下游步骤。
  • 重试:可以手动或自动重试失败步骤。
  • 日志:每个步骤都会保存执行日志,便于排查问题。

基于 MIT 许可证发布。