上传完成、转码完成、发布完成是三个状态
把上传、转码和发布塞进一个网页请求,会受到请求超时、客户端断线和工作进程重启影响。更稳妥的边界是:Web 接口负责鉴权和创建任务,处理节点负责媒体计算,发布步骤负责确认可用版本。本文适用于自有或已授权内容的点播处理。
待上传 → 上传中 → 校验中 → 排队中
↓
转码中
↓
产物校验 → 待发布 → 已发布
↓
失败 / 等待重试
每个状态都应带更新时间与原因,页面进度不能只依赖浏览器内存。任务失败后显示可操作的信息,例如“输入文件损坏”“存储上传失败”或“超出处理资源限制”,而不是统一显示“系统繁忙”。
上传:先确认文件完整,再交给处理节点
大文件可采用分片上传或由服务端授权客户端直传对象存储。后台只为当前用户分配允许的对象键、权限和有效期;上传完成通知还要由服务端核对实际对象、大小和校验信息,不能直接相信浏览器传来的成功标记。预签名地址具有访问能力,应避免进入公开页面、完整日志或分析事件。S3 预签名 URL 说明
以 S3 为例,分片上传包含创建、上传分片和完成合并的步骤,并可使用校验和检测完整性。不要把分片上传对象的 ETag 一概当作整个文件的 MD5。中断后未完成的分片也需要生命周期清理。S3 分片上传说明、未完成分片清理
文件扩展名和客户端 MIME 类型只能作线索。处理前还要检查真实媒体流、时长、分辨率、轨道数量与文件大小,并设置合理限制,防止一个异常输入占满处理资源。
数据库和队列如何避免重复执行?
| 记录 | 建议保存 | 作用 |
|---|---|---|
| 视频记录 | 业务标识、所有者、当前发布版本、状态 | 控制用户实际看到的内容 |
| 输入记录 | 对象键、校验信息、大小、探测结果 | 确定转码输入是哪一个版本 |
| 任务记录 | 任务 ID、模板版本、尝试次数、锁定时间、错误码 | 追踪处理和恢复过程 |
| 产物记录 | 清晰度、清单地址、封面、校验状态 | 通过验证后再发布 |
队列消息可能被重复投递,因此不能仅依赖“发送过一次”。可以用“输入版本 + 编码模板版本”形成任务唯一约束,处理节点领取任务时原子更新状态或取得租约,发布时确认任务版本仍然有效。数据库状态提交与队列发送之间也要有可恢复机制,例如可重发的任务记录与定期扫描,而不是发送失败就永远丢失任务。
工作进程重启后,超过租约时间的任务可重新领取;旧进程迟到提交时必须验证任务归属与版本。已发布的结果被重复回调时,应返回已有结果,不能再次创建重复业务记录。
FFmpeg 示例:先让一个受控样本跑通
下面是 Linux/macOS 终端的演示命令,输入为本地 input.mp4,输出到新建测试目录。使用前确认 FFmpeg 包含 libx264 与 AAC 编码能力。示例保留第一路视频和可选的第一路音频,不包含字幕、多清晰度或生产环境的资源限制。
mkdir -p output/job-demo
ffprobe -v error -show_format -show_streams \
-of json input.mp4
ffmpeg -nostdin -i input.mp4 \
-map 0:v:0 -map '0:a:0?' \
-c:v libx264 -pix_fmt yuv420p -crf 23 -preset medium \
-force_key_frames 'expr:gte(t,n_forced*6)' \
-c:a aac -b:a 128k \
-f hls -hls_time 6 -hls_playlist_type vod \
-hls_segment_filename 'output/job-demo/segment_%05d.ts' \
output/job-demo/index.m3u8
ffmpeg -nostdin -i input.mp4 -map 0:v:0 \
-frames:v 1 -update 1 output/job-demo/poster.jpg
ffprobe 可输出媒体格式与流信息;HLS 输出选项控制清单和切片,强制关键帧用于让分段目标更可控。示例不是任意素材都适用的万能模板:奇数尺寸、HDR、旋转元数据、特殊帧率等输入需要另外的预处理与验证。封面命令取首帧,正式系统应提供候选帧或人工选择,避免片头黑场。ffprobe 文档、FFmpeg 参数说明、HLS 输出选项
业务程序应以参数数组启动进程,不把用户文件名直接拼接成 shell 命令。输入来源、可访问协议、处理时长、内存、CPU 和临时磁盘都应有明确边界;转码节点无需持有数据库管理权限或整桶删除权限。
产物发布与清理要有先后顺序
- 每次任务写入独立的暂存目录或对象前缀,重新处理时不覆盖在线版本。
- 检查退出码、输出文件、播放时长、音画同步和清单引用;退出码为零也不代表业务样本完全符合要求。
- 先上传媒体切片与封面,再上传引用它们的清单,核对存储中的文件完整性。
- 从实际分发地址抽检播放,验证通过后原子切换数据库中的已发布版本。
- 保留旧版本至约定观察期结束,之后按数据库引用与生命周期策略清理,避免误删仍被播放的对象。
发布后的列表页只读取已发布版本。处理中可以在后台显示进度,但不要提前把未完成的 m3u8 暴露成可播放内容。取消或下架任务时也要有版本校验,防止后台已取消的任务稍后重新把视频发布出来。
失败恢复:区分能重试与必须修复的错误
| 错误类型 | 处理方式 | 需要保留的证据 |
|---|---|---|
| 短暂网络或存储失败 | 有限次数退避重试,使用同一任务标识 | 状态码、时间、对象键的安全摘要 |
| 媒体损坏或不支持的编码 | 停止自动重试,提示重新上传或调整处理模板 | 探测结果和脱敏错误摘要 |
| 磁盘、内存或执行时限不足 | 暂停领取新任务,调整资源后恢复 | 资源峰值与失败阶段 |
| 进程消失或节点重启 | 租约到期后重新领取,拒绝旧任务迟到发布 | 任务尝试次数和版本 |
重试要有上限和可见的终止状态。先监控队列等待时长、处理耗时、失败率、每分钟视频的计算消耗和临时存储占用,再决定扩容;无上限重试会把一个坏文件变成持续占用资源的任务。
何时需要定制开发,以及如何验收?
需要批量上传、多用户隔离、多个编码模板、断点恢复、人工审核或接入现有后台时,通常需要设计业务流程,而不只是调用一条 FFmpeg 命令。视频处理流水线定制可按输入类型、日处理时长、并发要求与存储环境评估开发和运行成本。
- 相同任务重复回调、重复投递,不产生重复发布和额外业务记录。
- 上传中断、处理节点重启、存储短暂失败后,都能恢复或明确结束。
- 无音轨、竖屏、长片、损坏文件和大尺寸输入均有可预期结果。
- 重新转码失败时旧版本仍可播放;取消任务后不会迟到发布。
- 后台能定位失败步骤,日志中没有上传凭证、访问 Token 或客户隐私。
视频处理系统常见问题
视频上传成功为什么还不能播放?
上传只说明输入文件已送达,后续还需要校验、转码、切片、上传产物和发布验证。页面应明确显示当前处理状态。
使用 GPU 就一定比 CPU 更合适吗?
不一定。需要比较输入格式、画质目标、吞吐、设备成本和编码支持,用实际样本测试后决定。
转码完成后可以立即删除原片吗?
应按内容授权、业务留存和重处理需求确定。删除原片会减少重新编码和修复能力,不能由单次任务成功自动决定。
