一条短视频从用户点击「发布」到别人流畅播放,中间要经过探测、转码、切片、分发、播放器适配五个阶段,任何一环卡住都会变成「上传转圈」或「播放卡顿」。媒体流水线是典型的「计算密集 + 状态复杂 + 成本敏感」系统:既要快,又要省,还要兼容千奇百怪的客户端。本文讲透这条链路:图片处理、视频转码、自适应码率、任务编排、弹性伸缩、存储分发、QoE 与降级预案。
前置:/miniblog-object-storage-images/(对象存储与图片处理)、/miniblog-content-delivery-cdn/(CDN 与边缘分发)、/miniblog-rich-text-content-pipeline/(内容处理管线设计)。
目录
- 1. 媒体流水线的全景:上传到播放
- 2. 图片处理:格式选择与有损权衡
- 3. 视频转码:编码器、码率与 CRF
- 4. 自适应码率:HLS/DASH 与分片策略
- 5. 任务编排:状态机、重试与优先级
- 6. 弹性伸缩:转码集群与成本控制
- 7. 存储与分发:对象存储与 CDN 回源
- 8. 质量与体验:卡顿率、首帧与 QoE
- 9. 可观测与降级:队列积压与故障预案
- 10. 速查表与一句话记忆
- 延伸阅读
1. 媒体流水线的全景:上传到播放
先建立端到端的心智模型,再逐段优化。
上传 → 探测(probe) → 转码(transcode) → 切片(package) → 分发(distribute) → 播放(playback)
探测:读容器/编码/分辨率/时长/旋转/色深
转码:按档位(ladder)生成多分辨率多码率版本
切片:切成 2~6 秒分片,生成 m3u8/mpd 清单
分发:上传对象存储,预热 CDN,生成播放 URL
播放:播放器按带宽选择档位,平滑切换
流水线的两种形态:
| 形态 | 触发时机 | 优点 | 缺点 |
|---|---|---|---|
| 同步(上传即转) | 用户等待 | 发布即可播 | 阻塞上传,成本高 |
| 异步(后台转) | 发布后 | 上传快 | 需占位与状态提示 |
主流做法是「异步 + 渐进可用」:先快速生成一个低清版本(秒级可用),再后台补齐高清档位,用户先能看、后变清。
渐进可用:
t+0s 原始文件落盘,生成封面
t+2s 生成 360p 低清档(可播)
t+30s 补齐 720p/1080p
t+2min 补齐多码率 ladder 与字幕
2. 图片处理:格式选择与有损权衡
图片是微型博客最频繁的媒体类型,格式选择直接决定带宽与体验。
| 格式 | 压缩率 | 透明 | 动图 | 兼容性 | 适用 |
|---|---|---|---|---|---|
| JPEG | 中 | 否 | 否 | 极好 | 照片 |
| PNG | 低 | 是 | 否 | 极好 | 截图/图标 |
| WebP | 高 | 是 | 是 | 好 | 通用替代 |
| AVIF | 最高 | 是 | 是 | 较新 | 高质量场景 |
| HEIC | 高 | 是 | 否 | 苹果生态 | iOS 上传 |
处理链路要点:
原图 → 元数据剥离(EXIF 隐私) → 方向校正 → 尺寸裁剪 → 压缩 → 多规格派生
派生规格示例:
thumb 200x200 (列表)
medium 720w (详情)
large 1440w (大图)
original (原图,仅作者可见)
质量参数是关键取舍:JPEG quality 75~82 通常是「肉眼无损」的甜点区,再往上体积陡增而画质提升有限。WebP/AVIF 在同等主观质量下可再省 25%~50% 体积,但编码更慢,需在流水线里权衡 CPU 与带宽成本。
质量甜点:
JPEG q=80 → 体积基准 100%
JPEG q=90 → 体积 ~180%,画质提升有限
WebP q=80 → 体积 ~65%
AVIF q=80 → 体积 ~50%,编码耗时 3~5 倍
工程建议:按客户端能力协商格式(Accept 头 + 兜底 JPEG),对热点图做「按需转码 + 长缓存」,冷图只存原图按需生成。
3. 视频转码:编码器、码率与 CRF
视频转码是流水线里最贵的一步,编码器选择决定成本与画质。
| 编码器 | 压缩效率 | 编码速度 | 解码兼容 | 硬件支持 |
|---|---|---|---|---|
| H.264 | 基准 | 快 | 极好 | 广泛 |
| H.265/HEVC | +40% | 慢 | 好 | 较广 |
| AV1 | +50% | 很慢 | 较新 | 新设备 |
| VP9 | +40% | 中 | 好 | 广泛 |
码率控制有三种模式,直接决定质量稳定性:
CBR 恒定码率:直播友好,画质随复杂度波动
VBR 可变码率:平均码率固定,峰值可冲高(点播常用)
CRF 恒定质量:按内容复杂度自适应码率(推荐点播)
CRF 是点播的首选:-crf 23 是 H.264 的常用甜点(18 更清、28 更省)。配合 -preset 调节速度与压缩率的权衡(veryfast 快但体积大,slow 慢但更省)。
ffmpeg -i in.mp4 -c:v libx264 -crf 23 -preset veryfast \
-c:a aac -b:a 128k -movflags +faststart out.mp4
| 档位 | 分辨率 | 目标码率(H.264) | 场景 |
|---|---|---|---|
| 240p | 426x240 | 300 kbps | 极弱网 |
| 360p | 640x360 | 600 kbps | 弱网 |
| 480p | 854x480 | 1.0 Mbps | 移动 |
| 720p | 1280x720 | 2.5 Mbps | 默认 |
| 1080p | 1920x1080 | 5.0 Mbps | WiFi |
档位设置要避免「码率倒挂」——低分辨率档的码率不应高于高分辨率档,否则播放器会做出反直觉选择。
4. 自适应码率:HLS/DASH 与分片策略
自适应码率(ABR)让播放器按实时带宽切换档位,是流畅播放的核心。
HLS 清单(master):
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=600000,RESOLUTION=640x360
360p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720
720p/index.m3u8
分片(segment)策略决定切换粒度与首帧速度:
| 分片时长 | 首帧 | 切换灵活性 | 请求数 | 适用 |
|---|---|---|---|---|
| 2s | 快 | 高 | 多 | 短视频/低延迟 |
| 4s | 中 | 中 | 中 | 通用 |
| 6s | 慢 | 低 | 少 | 长视频/电影 |
分片必须对齐关键帧(IDR):所有档位在同一时间点切分片,播放器切换时才能无缝拼接。这要求转码时强制 -g(GOP 长度)与分片时长一致。
对齐要求:
GOP 长度 = 分片时长 × 帧率
例:4s × 25fps = GOP 100 帧
所有档位统一 -g 100 -keyint_min 100 -sc_threshold 0
ABR 算法分两类:吞吐量优先(按实测带宽选档,激进)与缓冲区优先(按缓冲水位选档,保守)。生产播放器通常是混合策略:启动期保守、稳定后激进,缓冲区低于阈值时立刻降档。
5. 任务编排:状态机、重试与优先级
转码任务本质是分布式状态机,编排的健壮性决定「会不会丢片」。
任务状态机:
PENDING → PROBING → TRANSCODING → PACKAGING → UPLOADING → DONE
↘ FAILED → RETRY → (回到 TRANSCODING)
↘ CANCELED
编排要点:
- 幂等:每个任务用
(asset_id, profile)做幂等键,重复提交直接返回已有结果。 - 分级重试:网络类错误快速重试,编码类错误不重试(重试也不会成功),而是标记人工。
- 优先级队列:付费用户、热点内容走高优队列,避免被批量导入挤爆。
- 超时与心跳:Worker 定期心跳,失联任务重新入队,防止「卡死占位」。
优先级设计:
P0 付费/热点 → 独立队列,配额保障
P1 普通用户发布 → 默认队列
P2 历史批量重转 → 低优队列,夜间跑
| 失败类型 | 例子 | 处理 |
|---|---|---|
| 瞬时 | 网络抖动、存储超时 | 指数退避重试 3 次 |
| 永久 | 源文件损坏、编码不支持 | 标记失败,通知用户 |
| 资源 | OOM、磁盘满 | 换节点重试 |
| 业务 | 审核不通过 | 终止并回调 |
6. 弹性伸缩:转码集群与成本控制
转码是「突发、CPU 密集、可中断」的负载,天然适合弹性伸缩。
伸缩信号:队列深度 / 平均等待时长 / Worker 利用率
扩容:队列深度 > 阈值 且 等待 > SLO → 加 Worker
缩容:队列空 且 利用率 < 20% 持续 10min → 减 Worker
成本控制的三把刀:
| 手段 | 原理 | 节省 |
|---|---|---|
| 竞价实例 | 用可中断实例跑可重试任务 | 50%~70% |
| 硬件编码 | GPU/专用编码卡替代 CPU | 3~10 倍吞吐 |
| 按需转码 | 只转被访问的档位 | 视长尾而定 |
硬件编码(NVENC/QSV/VA-API)吞吐远高于 CPU 软编,但同等码率下画质略差,适合「低清档 + 长尾内容」;CPU 软编留给「高清档 + 热门内容」,两者混合是成本与质量的最优解。
混合策略:
低清档(≤480p) → GPU 硬编(快、便宜)
高清档(≥720p) → CPU 软编(慢、质量好)
长尾内容 → 按需转码(被访问才转)
7. 存储与分发:对象存储与 CDN 回源
转码产物要落到对象存储,再通过 CDN 分发,中间的「回源」策略决定成本。
上传:转码产物 → 对象存储(按 asset/profile/segment 组织)
分发:CDN 边缘缓存 → 命中直接返回,未命中回源
回源:回源带宽是成本大头,需尽量提高缓存命中率
关键设计:
- 不可变对象 + 长缓存:转码产物一旦生成就不再修改,可设
Cache-Control: max-age=31536000, immutable,命中率极高。 - 清单文件短缓存:
m3u8会随直播/新分片变化,设短 TTL(如 2s)或不缓存。 - 签名 URL 防盗链:播放 URL 带时效签名,防止被外站盗用带宽。
- 预热:热点内容发布后主动预热 CDN,避免「首发雪崩」。
| 对象类型 | 缓存策略 | 原因 |
|---|---|---|
| 视频分片 | 一年 immutable | 内容不变,命中率高 |
| 图片派生 | 一年 immutable | 同上 |
| 播放清单 | 短 TTL | 可能更新 |
| 封面 | 长 TTL | 基本不变 |
8. 质量与体验:卡顿率、首帧与 QoE
媒体体验必须用指标度量,否则优化无从下手。
| 指标 | 定义 | 目标示例 |
|---|---|---|
| 首帧时间 | 点击到第一帧 | P95 < 1.5s |
| 卡顿率 | 卡顿时长 / 播放时长 | < 0.5% |
| 起播失败率 | 无法起播比例 | < 0.3% |
| 平均码率 | 实际播放码率 | 越高越好 |
| 切换次数 | ABR 切档次数 | 越少越稳 |
首帧优化手段:
1. 首分片预加载:客户端提前拉第一片
2. 低清起播:先用 360p 起播,再升档
3. faststart:把 moov 前置,边下边播
4. 边缘预热:热点内容提前铺到边缘
卡顿治理的核心是「保守的 ABR」:宁可长期停在低档,也不要频繁升档后卡顿。缓冲区低于 3 秒时禁止升档,低于 1 秒时强制降档。同时用「码率上限」防止播放器在弱网下贪高。
9. 可观测与降级:队列积压与故障预案
流水线的可观测性要覆盖「任务、资源、体验」三层。
任务层:队列深度、等待时长、成功率、各状态任务数
资源层:Worker 利用率、GPU 占用、存储 IO、出网带宽
体验层:首帧、卡顿、起播失败(从播放器上报)
告警要按「积压程度」分级,而不是简单阈值:
| 级别 | 条件 | 动作 |
|---|---|---|
| 提醒 | 队列 > 1k 或等待 > 5min | 扩容 |
| 警告 | 队列 > 10k 或等待 > 30min | 扩容 + 限流新任务 |
| 严重 | 队列持续增长 30min | 降级:只转低清档 |
| 熔断 | 存储/CDN 故障 | 暂停转码,保发布 |
降级预案要预先定义:
降级顺序(保核心体验):
1. 关闭高清档,只转 360p(保可播)
2. 关闭图片派生,直接用原图(保可用)
3. 关闭水印/字幕等增值处理
4. 暂停非核心任务,保发布与播放
工程要点:媒体流水线的本质是「用计算换体验与带宽」的取舍。工程上要抓住四条主线:格式与编码的「压缩率 vs 成本」、ABR 与分片的「流畅 vs 清晰」、编排的「快 vs 稳」、弹性的「省 vs 峰值」。把「渐进可用」作为设计原则——先让内容秒级可播,再后台补齐高质量档位;把「分级降级」作为兜底手段——任何环节故障都能退到「能看」而不是「全挂」。
10. 速查表与一句话记忆
| 问题 | 一句话答案 |
|---|---|
| 图片用什么格式 | WebP/AVIF 优先,JPEG 兜底,剥离 EXIF |
| 质量甜点在哪 | JPEG q=75~82,再高体积陡增 |
| 点播码率怎么控 | CRF 恒定质量,preset 调速度 |
| 档位怎么设 | 240p~1080p 阶梯,避免码率倒挂 |
| ABR 怎么做 | 分片对齐 IDR,缓冲优先 + 混合策略 |
| 任务怎么编排 | 幂等键 + 分级重试 + 优先级队列 |
| 成本怎么降 | 竞价实例 + 硬件编码 + 按需转码 |
| 分发怎么省 | 不可变对象长缓存 + 短 TTL 清单 |
| 首帧怎么快 | 低清起播 + 首片预加载 + faststart |
| 故障怎么兜 | 渐进可用 + 分级降级 + 保核心 |
一句话记忆:媒体流水线 = 探测转码切片分发播放五段 + 图片格式协商(WebP/AVIF + JPEG 兜底)+ CRF 恒定质量与档位阶梯(防倒挂)+ HLS/DASH 分片对齐 IDR(无缝切换)+ 缓冲优先 ABR(流畅优先)+ 幂等分级重试优先级队列(不丢片)+ 竞价实例与硬件编码混合(省成本)+ 不可变长缓存与签名 URL(省带宽)+ 低清起播与首片预加载(快首帧)+ 渐进可用与分级降级(保核心)——用计算换体验,用降级保可用。
延伸阅读
- /miniblog-object-storage-images/ — 对象存储与图片派生
- /miniblog-content-delivery-cdn/ — CDN 缓存与边缘分发
- /miniblog-rich-text-content-pipeline/ — 内容处理管线设计
- /miniblog-performance-cost-optimization/ — 带宽与计算成本治理
- /miniblog-content-moderation-recommendation/ — 媒体内容审核
- 产品专题
- 分布式系统专题
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。