第 12 章 · AWS 实战参考

搭一个完整的 VOD 平台

本章你会看到:AWS 上搭一个 VOD 平台的完整服务清单、架构图、关键 API 调用、其他云的等价服务、真实的成本量级。

预计阅读时间:20 分钟

12.1AWS 媒体服务家族

AWS 把 VOD/直播相关服务叫 AWS Elemental。核心四件套:

服务 干什么
AWS Elemental MediaConvert文件转码(离线、VOD)
AWS Elemental MediaLive实时编码(直播)
AWS Elemental MediaPackage流媒体打包(HLS/DASH/CMAF)、DRM
AWS Elemental MediaStore / MediaTailor低延迟 origin / 广告插入

配合基础服务

服务 干什么
Amazon S3存储
Amazon CloudFrontCDN
AWS Lambda触发器、轻量处理
AWS Step Functions工作流编排
Amazon DynamoDB资产元数据存储
Amazon SNS/SQS事件通知、异步队列
Amazon CloudWatch监控告警

12.2官方参考架构

AWS 官方的 Video on Demand on AWS 方案架构:

┌──────────────┐                                              ┌──────────────┐
│   用户        │                                              │   Creator    │
│   观看        │                                              │  (Uploader) │
└──────────────┘                                              └──────────────┘
        ▲                                                                │
        │ ⑥ HTTPS                                                    │ ① PutObject
        │                                                                ▼
┌──────────────┐                                              ┌──────────────┐
│  CloudFront  │                                              │  S3 Source   │
│    (CDN)     │                                              │  Bucket      │
└──────────────┘                                              └──────────────┘
        ▲                                                                │
        │ ⑤ origin fetch                                            │ ② EventBridge
        │                                                                ▼
┌──────────────┐  ┌──────────────┐                       ┌──────────────┐
│ MediaPackage │◄──│  S3          │◄─────────────────────│ Step         │
│    -VOD      │  │ Destination  │                       │ Functions    │
│ (packaging)  │  │  Bucket      │                       └──────────────┘
└──────────────┘  └──────────────┘                              │
        │                      ▲                              │
        │ SPEKE                 │                              ▼
        ▼                      │                     ┌──────────────┐
┌──────────────┐             └─────────────────────│ MediaConvert │
│  DRM License │                                              │ (Transcode)  │
│ Server       │                                              └──────────────┘
│ (EZDRM等)   │                                                      │
└──────────────┘                                                      ▼
                                                                      ┌──────────────┐
                                                                      │   Lambda     │
                                                                      │ (post-proc, │
                                                                      │  notify)    │
                                                                      └──────────────┘

流程

1. Creator 上传文件到 S3 Source Bucket
2. S3 Event → Step Functions 被触发
3. Lambda 先 probe + 验证
4. Step Functions 调用 MediaConvert 转码
5. 转码结果写到 S3 Destination Bucket
6. MediaPackage-VOD 打包 HLS/DASH + DRM
7. CloudFront 作为 CDN 分发
8. 完成后 Lambda 通知用户

12.3一步步走一遍

步骤 1:准备 S3 Bucket

# Source bucket (上传原片)
aws s3 mb s3://my-vod-source --region us-east-1

# Destination bucket (转码产物)
aws s3 mb s3://my-vod-dest --region us-east-1

# 启用 EventBridge 通知
aws s3api put-bucket-notification-configuration \
  --bucket my-vod-source \
  --notification-configuration '{
    "EventBridgeConfiguration": {}
  }'

步骤 2:创建 IAM Role 给 MediaConvert 用

MediaConvert 需要从 S3 读、往 S3 写:

aws iam create-role --role-name MediaConvertRole \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy --role-name MediaConvertRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

步骤 3:MediaConvert Job 模板(最小可用)

{
  "Role": "arn:aws:iam::123456789012:role/MediaConvertRole",
  "Settings": {
    "Inputs": [{
      "FileInput": "s3://my-vod-source/episode01.mov",
      "AudioSelectors": {
        "Audio Selector 1": {"DefaultSelection": "DEFAULT"}
      }
    }],
    "OutputGroups": [{
      "Name": "CMAF",
      "OutputGroupSettings": {
        "Type": "CMAF_GROUP_SETTINGS",
        "CmafGroupSettings": {
          "Destination": "s3://my-vod-dest/ep01/",
          "SegmentLength": 4,
          "FragmentLength": 2,
          "WriteHlsManifest": "ENABLED",
          "WriteDashManifest": "ENABLED"
        }
      },
      "Outputs": [
        {
          "NameModifier": "_1080p",
          "VideoDescription": {
            "Width": 1920, "Height": 1080,
            "CodecSettings": {
              "Codec": "H_264",
              "H264Settings": {
                "RateControlMode": "QVBR",
                "QvbrSettings": {"QvbrQualityLevel": 8},
                "MaxBitrate": 5000000,
                "GopSize": 2,
                "GopSizeUnits": "SECONDS"
              }
            }
          },
          "AudioDescriptions": [{
            "CodecSettings": {
              "Codec": "AAC",
              "AacSettings": {
                "Bitrate": 128000,
                "SampleRate": 48000,
                "CodingMode": "CODING_MODE_2_0"
              }
            }
          }]
        },
        { "NameModifier": "_720p", /* ... 2500 kbps ... */ },
        { "NameModifier": "_540p", /* ... 1200 kbps ... */ },
        { "NameModifier": "_360p", /* ... 600 kbps ... */ }
      ]
    }]
  }
}

关键参数:

参数 说明
QvbrQualityLevel8QVBR 目标质量(1-10,越高越好)
MaxBitrate5,000,000峰值限制
GopSize2 SECONDS2 秒一个 GOP
SegmentLength44 秒切片
FragmentLength22 秒 fragment(子切片,for CMAF)

提交 Job:

aws mediaconvert create-job --cli-input-json file://job.json \
  --endpoint-url https://abc.mediaconvert.us-east-1.amazonaws.com

步骤 4:加 DRM (SPEKE)

在 CMAF OutputGroup 里加:

"Encryption": {
  "EncryptionMethod": "SAMPLE_AES",
  "SpekeKeyProvider": {
    "ResourceId": "episode01",
    "SystemIds": [
      "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",  // Widevine
      "94ce86fb-07ff-4f43-adb8-93d2fa968ca2",  // FairPlay
      "9a04f079-9840-4286-ab92-e65be0885f95"   // PlayReady
    ],
    "Url": "https://speke.ezdrm.com/v2",
    "CertificateArn": "arn:aws:acm:..."
  }
}

SPEKE URL 指向 DRM 厂商(EZDRM/PallyCon等)的 endpoint。

步骤 5:CloudFront 分发

创建一个 distribution 指向 S3 Destination Bucket:

aws cloudfront create-distribution --distribution-config file://cf-config.json

关键配置:

Origin: S3 Destination Bucket
Viewer Protocol Policy: Redirect HTTP to HTTPS
Allowed Methods: GET, HEAD
Cache Policy: Managed-CachingOptimizedForUncompressedObjects
Origin Access Control: 启用,防止绕过 CloudFront 直接访问 S3
Signed URLs: 需要时启用 Trusted Key Groups

步骤 6:Signed URL 生成

客户端请求播放时后端生成短时效签名 URL:

# Python 示例
from datetime import datetime, timedelta
import boto3

cf_signer = boto3.client('cloudfront-signer', ...)

def generate_signed_url(video_path, user_id, expires_in=3600):
    url = f"https://d1234.cloudfront.net/{video_path}"
    expires = datetime.utcnow() + timedelta(seconds=expires_in)
    # 用 CloudFront key-pair 签名
    signed = cf_signer.generate_presigned_url(url, date_less_than=expires)
    return signed

步骤 7:Step Functions 编排

状态机串起整个流程(见第 11 章 §11.11 编排工具)。

12.4Terraform 一键部署片段

用 Terraform 声明基础设施:

# Source bucket
resource "aws_s3_bucket" "source" {
  bucket = "my-vod-source"
}

# Destination bucket
resource "aws_s3_bucket" "dest" {
  bucket = "my-vod-dest"
}

# EventBridge rule to trigger Step Functions on S3 upload
resource "aws_cloudwatch_event_rule" "upload" {
  name = "vod-upload-trigger"
  event_pattern = jsonencode({
    source = ["aws.s3"]
    "detail-type" = ["Object Created"]
    detail = {
      bucket = { name = [aws_s3_bucket.source.bucket] }
    }
  })
}

# Step Functions state machine
resource "aws_sfn_state_machine" "vod_pipeline" {
  name     = "vod-pipeline"
  role_arn = aws_iam_role.sfn_role.arn
  definition = file("${path.module}/vod_pipeline.asl.json")
}

resource "aws_cloudwatch_event_target" "sfn" {
  rule = aws_cloudwatch_event_rule.upload.name
  arn  = aws_sfn_state_machine.vod_pipeline.arn
  role_arn = aws_iam_role.event_bridge_role.arn
}

# CloudFront distribution
resource "aws_cloudfront_distribution" "vod" {
  origin {
    domain_name = aws_s3_bucket.dest.bucket_regional_domain_name
    origin_id   = "s3-vod-dest"
    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.vod.cloudfront_access_identity_path
    }
  }

  enabled             = true
  default_root_object = ""

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "s3-vod-dest"
    viewer_protocol_policy = "redirect-to-https"
    cache_policy_id = data.aws_cloudfront_cache_policy.caching_optimized.id
    trusted_key_groups = [aws_cloudfront_key_group.vod.id]
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

12.5成本估算

MediaConvert 转码成本

按"输出分钟数 x 编码复杂度"计费:

档位 单价(美东 us-east-1)
Basic SD (< 30 fps, < 720p, AVC)$0.0075 / output min
Basic HD (< 30 fps, 720p-1080p, AVC)$0.015 / output min
Pro HD (60 fps 或 HEVC 或 HDR)$0.030 / output min
Pro UHD (4K+)$0.060 / output min
AV1 加价约 2-3x

💰 一部 90 分钟电影 x 6 档 (4 H.264 + 2 H.265)

90 min x 4 档 x $0.015 = $5.4 (H.264)
90 min x 2 档 x $0.030 = $5.4 (H.265)
总转码成本 ≈ $10.8 / 电影

S3 存储

• 存储 Standard:$0.023 / GB / 月(us-east-1)
• 一部电影所有版本 ~ 3 GB → $0.07 / 月
• 大库(10 万小时):约 1 PB → $23,000 / 月
• 冷内容用 S3 Glacier 可省 80%

CloudFront 出站带宽

按区域 $0.005–$0.08 / GB,阶梯折扣。

MediaPackage JIT packaging

约 $0.065 / GB(源文件流量)。大量访问热门内容划算。

12.6其他云的等价服务

AWS 阿里云 腾讯云 Google Cloud Azure
S3OSSCOSGCSBlob Storage
MediaConvertVOD / IMMVOD / MPSTranscoder APIMedia Services
MediaPackageVOD DRMVOD DRMMedia CDNMedia Services DRM
CloudFrontCDN / DCDNCDN / ECDNCloud CDN / Media CDNAzure CDN
Step FunctionsServerless WorkflowSCF + WorkflowRunWorkflowsDurable Functions
LambdaFC / SAESCFCloud FunctionsAzure Functions

选云建议:

• 全球业务、海外为主:AWS(覆盖最广)
• 中国大陆为主:阿里云 / 腾讯云
• 短剧出海:AWS + 阿里云国际 / 火山引擎(多云分发)

12.7一个典型短剧 APP 的 AWS 账单(推断)

按 DAU 2M、日均 30 分钟观看、720p 主码流推断:

科目 月成本量级
S3 存储 (10 PB)$50K-$150K
MediaConvert (每天 100 集新上)$1K-$5K
CloudFront (24 PB/月)$400K-$800K
MediaPackage JIT$50K-$150K
Lambda + Step Functions$5K-$20K
DynamoDB + RDS$10K-$30K
DRM SaaS$20K-$80K
合计$500K-$1.2M

CDN 带宽是绝对大头

降本三板斧:更好的编解码器、Per-Title 编码、多 CDN 竞价。

12.8从 0 到生产上线 Roadmap

第 1 周:最小可用 DEMO

• 开 AWS 账号,启用 S3、MediaConvert、CloudFront
• 手动跑一个 MediaConvert Job,转出一个 HLS
• 用 Safari 打开 m3u8 能播 ✅

第 2-4 周:自动化管线

• Step Functions 串联:S3 Upload → MediaConvert → S3 → CloudFront
• 后端生成 Signed URL
• iOS/Android APP 集成播放器

第 2-3 个月:生产特性

• 多档码率 + per-title 优化
• DRM 接入(EZDRM / PallyCon)
• QoE 数据接入 Mux 或自建
• 多 CDN 调度

第 4-6 个月:规模化

• H.265 / AV1 档位
• LL-HLS(如果做直播)
• 多区域部署 + 跨区复制
• 成本优化(Spot、Glacier 冷归档)

阶段 目标
第 1 周手动跑一个 MediaConvert Job → Safari 播 m3u8 ✅
第 2-4 周Step Functions 自动化 + Signed URL + APP 集成播放器
第 2-3 月多码率 + DRM + QoE 接入 + 多 CDN
第 4-6 月H.265/AV1 + 多区域 + 成本优化(Spot/Glacier)

12.9常见陷阱

❌ CloudFront 签名 URL 缓存命中率为 0

原因:签名参数(Signature, Expires, Key-Pair-Id)进入了 cache key。

解决:在 Cache Policy 里只把 path 作为 cache key,signed parameters 放 Query String 但不参与缓存

❌ MediaConvert 输出文件异常大

原因:没配 QVBR 或 MaxBitrate,CRF 太低导致峰值爆炸。

解决QvbrQualityLevel: 7-8 + MaxBitrate 约束。

❌ HLS 在 iOS 上卡在加载

原因:Master Playlist 里缺 CODECS 属性。

解决:确保每个 EXT-X-STREAM-INF 都带 CODECS="avc1.xxxxxx,mp4a.40.2"

❌ 跨境分发延迟高

原因:CloudFront 回源到 us-east-1 S3 对亚洲用户延迟高。

解决:启用 CloudFront Origin Shield,放在离 origin 近的地方;或者 S3 跨区复制,让 CloudFront 就近回源。

📌 本章要点回顾

1. AWS 核心四件套:MediaConvert + MediaPackage + CloudFront + S3
2. Step Functions 做编排,Lambda 做轻处理。
3. 用 SPEKE 接 DRM 托管服务。
4. 生产环境用 Terraform 声明式管理
5. 成本里 CDN 带宽是大头,其次是存储,转码相对便宜。
6. 其他云都有对等服务;选云按市场定位。
7. 从 MVP → 生产一般 2-6 个月

🎉🎊🏆

恭喜读完全书!

你已经系统了解了 VOD 流媒体的完整技术栈 —— 从视频基础、编解码、容器封装、流媒体协议、DRM 加密、CDN 分发、播放器、QoE 监控、AI/ML 增强、端到端工作流,一直到 AWS 实战。

下一步建议:

• 按本章 12.8 的 Week 1 动手搭一个 DEMO
• 重读 ReelShort 案例分析
• 查阅术语速查表

← 上一章:端到端工作流 目录 术语速查表 →

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