VOD 深度剖析 第 11 部分:端到端工作流——从上传到播放

完整的 10 步 VOD 生产流水线:上传、内容审核、探测、转码、封装、发布、CDN 预热,以及使用 Step Functions 和 Temporal 进行编排、灾难恢复。

zhuermu··20 分钟
vodstreamingworkflowstep-functionstranscodingpipeline

本文是 VOD 流媒体深度剖析 系列的第 11 部分。


完整流水线概览

一段视频从文件交付到全球播放,至少要经历 10 个步骤:

①Upload  →  ②Content Scan  →  ③Probe  →  ④Transcode  →  ⑤Package+Encrypt
   ↓            ↓                ↓          ↓               ↓
   │        NSFW / copyright   ffprobe   Multi-rate       CMAF +
   │        fingerprint /      resolution H.264+H.265     DRM
   │        virus scan                   +AV1             Signing

⑥Publish to Storage → ⑦Write Metadata → ⑧CDN Pre-warm → ⑨Notify → ⑩Monitor
   ↓                    ↓                 ↓               ↓         ↓
   S3 / Object        MySQL / ES        Major region    Push /     QoE
   Storage             Index             edge nodes     Homepage   Regression

每一步都可能失败。成熟的平台会在每个阶段都配备 重试、告警和人工兜底方案


步骤 1:上传——把大文件送上云

挑战

  • 源文件往往有 5–50 GB(ProRes / DNxHD)
  • 网络不可靠(跨境、办公室 WiFi)
  • 用户可能在上传中途关闭笔记本或断网

分片上传(Multipart Upload)

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

Large file ────► [Chunk 1] [Chunk 2] [Chunk 3] ... [Chunk N]
                     │         │         │             │
                     ▼         ▼         ▼             ▼
                S3 Multipart concurrent upload (5-10 parallel)


                    Merge after all complete

优势:并行加速、失败可续传(只需重试失败的分片)、S3/GCS/Azure Blob 原生支持。

去重(MD5/CRC 预校验)

上传前,客户端先计算文件的 MD5 哈希:

Client → Backend: "Uploading file, md5=abc123"
Backend → Client: "Already have it, skip upload"   ← instant
              or
               "Not found, please upload"

S3 分片上传 API(三步)

import boto3

s3 = boto3.client('s3')

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

# 2. Upload each 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. Complete and merge
s3.complete_multipart_upload(
    Bucket='my-bucket', Key='video.mov',
    UploadId=upload_id,
    MultipartUpload={'Parts': parts})

步骤 2:内容扫描——合规审核

上传的文件先进入 隔离桶(quarantine bucket)(而非生产存储)。内容必须通过审核后才能晋升到生产环境。

必要检查项

检查项工具
病毒扫描ClamAV、VirusTotal API
NSFW 检测AWS Rekognition Content Moderation
暴力 / 血腥 / 政治敏感内容同上
版权指纹识别Audible Magic(音乐)、ACRCloud
人脸识别(如有需要)AWS Rekognition
字幕合规关键词过滤、区域适配

人工审核

AI 只是第一道过滤。高价值或处于边界的内容会进入人工审核队列:

  • 审核员观看(抽样或完整观看)
  • 标记为合规或不合规
  • 记录判断理由

步骤 3:探测(Probe)——转码前先做校验

ffprobe 扫描文件以提取元数据:

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

可提取:分辨率、帧率、编解码器、音轨、采样率、时长、可变帧率标记、HDR 元数据。

校验规则

  • 时长 < 30 秒 → 拒绝(不是有效的剧集)
  • 分辨率低于 720p → 拒绝(质量不足)
  • 帧率不在 60 之内 → 告警
  • 标记为 HDR 但色彩空间不是 BT.2020 → 标记待修正或拒绝

步骤 4:转码——核心生产环节

产物清单

单个源文件通常会产出:

/vod/ep-001/
  mezz/original.mov              ← Source backup (cold storage)
  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 (flagship devices)
  audio_en.mp4                   ← English AAC
  audio_zh.mp4                   ← Chinese AAC
  subs_en.vtt                    ← English subtitles
  subs_zh.vtt                    ← Chinese subtitles
  thumbnails.vtt + sprite.jpg    ← Thumbnail preview (scrub bar)

并行加速

单集视频可能需要 10 多个输出档位。有两种并行策略:

按档位并行(简单)

Transcode cluster:
  Worker 1: Source → 360p H.264
  Worker 2: Source → 720p H.264
  Worker 3: Source → 1080p H.264
  Worker 4: Source → 720p H.265
  ...all workers run simultaneously

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

Split source at IDR boundaries into N segments
Each segment sent to a different worker for independent transcoding
Concatenate bitstreams at the end

Netflix 和 YouTube 会启动数百台云实例并行转码一部电影,大约一小时即可完成。

转码服务选型

服务特点
自建 ffmpeg 集群控制力最强、大规模下成本最低、运维负担最重
AWS MediaConvert按分钟计费、QVBR、集成 HDR/DRM
Bitmovin / Mux对开发者友好、企业级

成本优化

  • Spot / 抢占式实例 + 检查点续跑:可省 70–80%
  • 长尾内容:只做 H.264(节省转码与存储成本)
  • 热门内容:追加 H.265/AV1 档位

步骤 5:封装与加密

转码后的 MP4 需要转换成流媒体格式。参见 第 5 部分(协议)第 8 部分(DRM)

Transcoded MP4s


Shaka Packager / MediaPackage / mp4box


Output:
  CMAF fMP4 segments
  HLS master.m3u8 + media.m3u8
  DASH manifest.mpd
  (Optional) CENC/CBCS encrypted segments + license metadata

步骤 6–7:发布到存储 + 写入元数据

转码/封装后的资产上传到 生产存储(通常是一个独立的 S3“生产桶”):

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

同时写入业务数据库:

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

更新搜索索引(Elasticsearch / Algolia)以便被检索到。


步骤 8:CDN 预热

参见 第 7 部分:CDN 分发

不要等第一波用户来触发回源拉取。 对新内容和预期会火的内容进行预热,把 init 分片和前 5–10 个媒体分片提前推送到全球边缘节点。


步骤 9:通知与上线

  • CMS 状态从“处理中”切换为“就绪”
  • 向订阅者推送通知:“你关注的剧集更新了”
  • 更新首页推荐 / 排行榜
  • 激活广告素材(如为商业化内容)

步骤 10:监控与回归

上线后持续监控:

  • 播放成功率
  • QoE 指标是否在正常区间内(参见 第 10 部分
  • 标记异常内容(例如某一集卡顿率异常偏高)
  • 发现问题 → 重新转码或回滚

编排:把各步骤串联起来

上述 10 个步骤必须按顺序可靠执行,并支持 重试、并行和失败分支。这些逻辑不可能硬编码进一个脚本里。

常见编排工具

工具特点适用场景
AWS Step FunctionsServerless、可视化、与 AWS 深度集成AWS 原生场景,AWS VOD 方案的默认选择
Temporal分布式工作流、强一致性、类型安全自管控制面 / 多云
Airflow批量 ETL、定时任务数据处理、离线分析
Argo WorkflowsKubernetes 原生K8s 团队
自研(Kafka 驱动)事件驱动,每一步发布下一个事件追求最大定制化

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 内置了重试、超时、分支以及可视化的执行流程图。


灾难恢复与回滚

多区域备份

  • 源文件(mezzanine 母版)通过 S3 跨区域复制(Cross-Region Replication)跨区备份
  • 热门内容存储在多个区域(就近分发 + 故障转移)

回滚场景

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

数据备份

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

一个典型的时间线

一部 60 分钟的电影从上传到全球可用:

T+0min    Creator uploads mezzanine to quarantine bucket
T+5min    Upload complete → triggers Step Functions
T+7min    NSFW + virus scan complete
T+8min    ffprobe validation passes
T+10min   Parallel transcode starts (H.264 x4 + H.265 x2 + AV1 x1)
T+70min   All transcodes complete (~1x real-time, parallel tiers)
T+72min   Packager generates HLS + DASH + DRM
T+73min   Assets uploaded to production S3
T+74min   CDN pre-warming complete (NA / EU / APAC)
T+75min   Metadata written, search index updated, notifications sent
T+75min   Live ✅

短视频/短剧应用(每集 60–90 秒)能在几分钟内跑完整条流水线。


关键要点

  1. VOD 流水线包含 10 个主要步骤——每一步都可能失败,都需要重试 + 告警。
  2. 上传:分片 + MD5 去重。存储:隔离桶 + 内容扫描。
  3. 转码前必须做 ffprobe 校验。
  4. 转码 是最耗时的步骤——按档位或 GOP 并行 + 使用 Spot 实例。
  5. 封装 + DRM 是发布前的最后一步。
  6. CDN 预热 对新内容上线至关重要。
  7. Step Functions / Temporal 是首选的编排工具。
  8. 从第一天起就要规划好 灾难恢复和回滚

上一篇: 第 10 部分:QoE 指标

下一篇: 第 12 部分:在 AWS 上构建 VOD

参考资料

  1. AWS Step Functions Developer Guide — AWS Documentation
  2. Temporal documentation — Temporal
  3. AWS Elemental MediaConvert User Guide — AWS Documentation