第 11 章 · 端到端工作流:从上传到发布的完整生产线

Chapter 11 of 12 · 预计阅读 18 分钟

本章你会理解:一个视频从导演把文件交给你到全球用户能看到,完整要经过哪些环节、每步在解决什么问题、用什么工具编排。

11.1VOD 工作流全景

看一眼,感受下复杂度:

①上传②入库扫描③探针校验④转码⑤打包加密
  ↓          ↓             ↓           ↓          ↓
  │     NSFW / 版权     ffprobe    多码率 H.264  CMAF +
  │     指纹 / 病毒     分辨率     + H.265      DRM
  │                               + AV1       签名
  ↓
⑥发布到存储⑦写元数据⑧CDN 预热⑨通知上线⑩监控
  ↓            ↓            ↓           ↓         ↓
  S3 / OSS    MySQL/ES     主要地区     推送/首页    QoE
  对象存储    索引         边缘节点     排期        回归

每一步都可能出问题。一个成熟平台会在每步有重试、告警、人工兜底

11.2① 上传:把大文件稳稳送到云

挑战:

• 母版文件常 5-50 GB(ProRes / DNxHD)
• 网络不稳定(跨国、办公室 WiFi)
• 用户可能在上传中关电脑 / 断网

分片上传(Multipart Upload)

把文件切成 5-100 MB 的片段,并发上传:

大文件 ────► [片段1] [片段2] [片段3] ... [片段N]
                 │       │       │           │
                 ▼       ▼       ▼           ▼
            S3 Multipart 并发上传(5-10 并行)
                         │
                         ▼
                 全部完成后合并

好处:

• 并行加速
• 失败只重传单个片段(断点续传)
• S3/OSS/COS 都原生支持

秒传(MD5/CRC 预检查)

上传前客户端算 MD5,发给后端:

客户端 → 后端: "我要上传文件,md5=abc123"
后端  → 客户端: "这个文件我已经有了,你不用上传"  ← 秒传
               or
               "没有,请开始上传"

实战:S3 Multipart 的三步 API

import boto3

s3 = boto3.client('s3')

# 1. 发起 multipart upload
resp = s3.create_multipart_upload(Bucket='my-bucket', Key='video.mov')
upload_id = resp['UploadId']

# 2. 上传每个 part
parts = []
for i, chunk in enumerate(chunks, start=1):
    resp = s3.upload_part(
        Bucket='my-bucket', Key='video.mov',
        UploadId=upload_id, PartNumber=i,
        Body=chunk)
    parts.append({'PartNumber': i, 'ETag': resp['ETag']})

# 3. 完成合并
s3.complete_multipart_upload(
    Bucket='my-bucket', Key='video.mov',
    UploadId=upload_id,
    MultipartUpload={'Parts': parts})

11.3② 入库扫描:内容合规

上传到"隔离区" bucket(不是正式存储),过完审核才能进正库。

必做检查

检查 工具
病毒扫描ClamAV、VirusTotal API
NSFW 检测AWS Rekognition Content Moderation、阿里云绿网
暴力/血腥/政治敏感同上
版权指纹Audible Magic(音乐)、ACRCloud
人脸识别(按需)AWS Rekognition、自研
字幕合规关键词过滤、地域适配

人工复审

AI 只能初筛。高价值或不确定的内容进入人工队列:

• 审核员看一遍(抽样或全量)
• 标记合规或不合规
• 记录理由

11.4③ 探针校验(Probe)

ffprobe 扫一遍文件,读出元数据:

ffprobe -v error -show_format -show_streams -of json input.mov > probe.json

获取:

• 分辨率、帧率、编码
• 音轨数、采样率
• 时长
• 是否有变帧率、异常时间戳
• 是否含 HDR 元数据

校验规则:

• 时长 < 30 秒 → 拒绝(不是剧集)
• 分辨率低于 720p → 拒绝(画质不够)
• 帧率异常(不是 23.976/25/29.97/30/50/60)→ 警告
• HDR 但色彩空间不是 BT.2020 → 修正或拒绝

11.5④ 转码:核心生产环节

产出物清单

一个源文件转码后通常产出:

/vod/ep-001/
  mezz/original.mov              ← 母版备份(冷存)
  v_360p.mp4                     ← H.264 360p
  v_480p.mp4                     ← H.264 480p
  v_720p.mp4                     ← H.264 720p
  v_1080p.mp4                    ← H.264 1080p
  v_720p_hevc.mp4                ← H.265 720p
  v_1080p_hevc.mp4               ← H.265 1080p
  v_720p_av1.mp4                 ← AV1 720p (旗舰机)
  audio_en.mp4                   ← English AAC
  audio_zh.mp4                   ← Chinese AAC
  subs_en.vtt                    ← English subtitle
  subs_zh.vtt                    ← Chinese subtitle
  thumbnails.vtt + sprite.jpg    ← 缩略图预览(进度条悬停缩略图)

并行加速

一个剧集可能要转 10+ 个档位。如果串行,等半天。并行切分有两种

① 按档位并行(简单)

每个 Worker 负责一个档位。N 个档位 = N 个 Worker 同时转。

转码集群:
  Worker 1: 源 → 360p H.264
  Worker 2: 源 → 720p H.264
  Worker 3: 源 → 1080p H.264
  Worker 4: 源 → 720p H.265
  ...所有 Worker 同时跑

② 按 GOP 切分并行(复杂但快)

把源文件按 IDR 边界切成 N 段,每段丢给不同 Worker 独立转码,最后拼接 bitstream。

把源文件按 IDR 边界切成 N 段
每段丢给不同 Worker 独立转码
最后拼接 bitstream

Netflix / YouTube 在云上动用几百个实例并行转一部电影,一小时完成。

转码服务选择

服务 特点
自建 ffmpeg 集群控制力最强、成本最低(大规模)、运维麻烦
AWS MediaConvert按分钟付费、QVBR、HDR/DRM 集成好
阿里云 VOD / 腾讯云 VOD国内业务接入简单
Bitmovin / Mux开发者友好、企业级
BytePlus VOD短剧场景优化好

成本优化

Spot / Preemptible 实例 + 断点续转:省 70-80%
长尾内容只做 H.264(节省转码成本 + 存储成本)
热门内容追加 H.265/AV1

11.6⑤ 打包与加密

转码后的 MP4 要变成流媒体格式:

转码产出的 MP4
        │
        ▼
Shaka Packager / MediaPackage / mp4box
        │
        ▼
产出:
  CMAF fMP4 切片
  HLS master.m3u8 + media.m3u8
  DASH manifest.mpd
  (可选)CENC/CBCS 加密切片 + License 元数据

11.7⑥-⑦ 发布到存储 + 写元数据

转码/打包产物上传到正式存储(常是 S3 的"生产 bucket"):

/vod-production/ep-001/
  init.mp4
  seg_*.m4s
  master.m3u8
  manifest.mpd
  thumbnails/...

同时写业务数据库:

INSERT INTO episodes (
    episode_id, drama_id, title, duration_sec,
    manifest_url, thumbnail_url,
    status, publish_at, ...
) VALUES (...);

写搜索索引(Elasticsearch / Algolia)以便用户搜索。

11.8⑧ CDN 预热

核心原则

不要等第一批用户来触发回源。对新剧、爆款剧做主动预热。

预热内容包括 init segment + 前 5-10 段 + 所有码率的首段,覆盖北美/欧洲/亚太主要 PoP 节点。

11.9⑨ 通知与上架

• CMS 里状态从 "processing" → "ready"
• 推送给订阅用户:"你追的剧新一集来了"
• 首页推荐位 / 榜单更新
• 广告素材上架(如果是付费剧)

11.10⑩ 监控与回归

上线后持续监控:

• 播放成功率
• QoE 指标是否正常
• 反馈到 CMS 的异常(比如某一集特别多卡顿)
• 发现问题 → 重新转码或回滚

11.11编排工具:把流程串起来

上面 10 步要可靠地一步接一步执行,还要处理重试、并行、失败分支。不能用一个大脚本硬编码。

常用编排工具

工具 特点 适合
AWS Step FunctionsServerless、可视化、紧密集成 AWSAWS 原生,官方 VOD 方案默认
Temporal分布式工作流、强一致、类型安全自研控制面 / 跨云
Airflow批量 ETL、定时任务数据处理,VOD 里用于离线分析
Argo WorkflowsKubernetes 原生K8s 团队
自研(Kafka 驱动)事件驱动,每步 publish 下一事件追求极致定制

Step Functions 示例(简化)

{
  "StartAt": "Probe",
  "States": {
    "Probe": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:...:ProbeVideo",
      "Next": "ParallelTranscode"
    },
    "ParallelTranscode": {
      "Type": "Parallel",
      "Branches": [
        {"StartAt": "Transcode360p", "States": {
          "Transcode360p": {"Type": "Task", "Resource": "arn:aws:mediaconvert:...", "End": true}}},
        {"StartAt": "Transcode720p", "States": {
          "Transcode720p": {"Type": "Task", "Resource": "arn:aws:mediaconvert:...", "End": true}}},
        {"StartAt": "Transcode1080p", "States": {
          "Transcode1080p": {"Type": "Task", "Resource": "arn:aws:mediaconvert:...", "End": true}}}
      ],
      "Next": "Package"
    },
    "Package": {"Type": "Task", "Resource": "...Package...", "Next": "Prewarm"},
    "Prewarm": {"Type": "Task", "Resource": "...Prewarm...", "Next": "Notify"},
    "Notify": {"Type": "Task", "Resource": "...Notify...", "End": true}
  }
}

Step Functions 自带重试、超时、分支、可视化。

11.12灾备与回滚

多地区备份

• 源文件(母版)跨 region 备份(S3 Cross-Region Replication)
• 热门内容在多 region 有副本(就近分发 + 容灾)

回滚场景

• 新剧上线后发现内容问题 → 一键下架 + CDN 失效缓存
• 转码版本有 bug → 切回上个版本的 manifest

数据备份

• 元数据 DB 每日备份
• 用户观看进度(存大量)→ 分层存储:热数据在 Redis,冷数据归档到 S3 Glacier

11.13一个典型的工作流时间线

一部 60 分钟的电影从上传到上线:

T+0min    导演上传 mezz 文件到隔离 bucket
T+5min    上传完成 → 触发 Step Functions
T+7min    NSFW + 病毒扫描完成
T+8min    ffprobe 校验通过
T+10min   启动并行转码 (H.264 x 4档 + H.265 x 2档 + AV1 x 1档)
T+70min   全部转码完成(60 分钟电影约需 1x 实时,并行多档)
T+72min   Packager 打包 HLS+DASH+DRM
T+73min   上传到生产 S3
T+74min   CDN 预热完成(北美/欧洲/亚太)
T+75min   写元数据、ES 索引、通知
T+75min   上线 ✅

短剧 APP 场景因为单集 60-90 秒,端到端在几分钟内完成。

本章要点回顾

1. VOD 工作流 10 大步,每步都可能出问题,要有重试和告警。
2. 上传用 Multipart + MD5 秒传;存储用隔离 bucket + 扫描。
3. ffprobe 探针是转码前必做。
4. 转码占整个流程最长时间,靠并行 + Spot 实例降本。
5. Packager + DRM 是发布前的最后一步。
6. CDN 预热对新剧上架至关重要。
7. Step Functions / Temporal 是常见编排工具。
8. 做好灾备、回滚的预案。

← 上一章:QoE 数据体系 目录 下一章:AWS 实战参考 →

© 2026 Zmead · VOD 流媒体技术全解