3.3 视频与文档预览:转码与格式
场景:传上来的视频不能看
网盘里存了一堆演示视频,但只能下载后播放体验极差。另外团队沉淀了大量 pptx 与 docx,每次分享都要对方下载再用 Office 打开,手机上更是没法看。需求很明确:视频在线预览,文档在线翻页。
视频预览的难点不在播放器,在格式。用户传的 mov、mkv、avi 浏览器大多不支持,转成 mp4 才能播。文档则要么转图片,要么转 pdf,浏览器才认。这两件事自己写都要命,交给 CI 的媒体处理与文档转码,几天就能上线。
方案:预览格式决策
先定视频转码的目标参数。过高浪费带宽与转码费,过低画质差:
| 参数 | 取值 | 理由 |
|---|---|---|
| 目标容器 | mp4 | 浏览器通用 |
| 视频编码 | h264 | 兼容性最好 |
| 码率 | 原码率或略降 | 保留演示价值 |
| 分辨率 | 上限 1080p | 手机够看 |
文档转码的输出格式二选一:
| 输出 | 优点 | 缺点 | 我们的选择 |
|---|---|---|---|
| pdf 版 | 保真,可下载 | 渲染靠浏览器插件 | 主力 |
| 图片版 | 纯前端渲染无依赖 | 文件多、文字不可选 | 备用 |
文档建议 pdf,浏览体验好且也能下载。某些文档类型 CI 支持有限时退到图片。预览收益是真实的:分享后对方打开率从三成提到八成,下载这个动作对多数人就是劝退。
配置:触发转码与拼接
转码我们走两路触发:上传后由 SCF 事件触发自动转码;或详情页打开时按需触发。前者消费算力稳定但转码量随上传量涨,后者省算力但首次打开慢。折中方案是准入制:上传时转标清,详情页提供高清按需转。核心调用就是 CI 的媒体任务接口:
// 提交转码任务:输出到预览前缀,输出 mp4
job := ci.MediaProcessJob{
Input: key,
Output: "preview/" + id + ".mp4",
Operation: MediaTranscode{
Container: "mp4", Video: "h264", Resolution: "1080p",
},
}
ci.CreateMediaJob(ctx, job)
转码任务异步执行,完成后 COS 写入结果对象,前端轮询状态或等 SCF 回调即可。转码时长粗略等于视频时长的二分之一到五分之一,10 分钟视频约等 2 到 5 分钟,完整版在 SCF 回调里讲,这里不展开。
文档转码类似,调 CI 的文档处理接口输出 pdf。两类任务共用一套回调与通知管道,前端同一个进度条组件,用户感知不到差异。
踩坑:预览链路的四个坑
第一个坑,转码失败是常态。奇码率的视频、加密的文档都可能失败,转码失败必须明确提示并提供原始下载兜底,别把失败藏起来让用户干等。我们的转码成功率约 92%,失败提示设计好了用户也不烦。
第二个坑,时长。一个 1 小时的会议录像转码要等十几分钟,用户体验不可接受。我们的做法是预览只转前 10 分钟或标清版,完整版异步转,先让用户看到东西再谈完整。
第三个坑,转码费按输出时长收。一段视频被反复观看不花钱,但反复转码就是烧钱。转码结果建议永久缓存,除非源文件被替换。我们也遇到过转码缓存失效重跑的问题,走文件指纹兜底。
第四个坑,视频版权与内容安全。预览视频默认允许被下载、被翻录,对内部资料没问题,对外分享时把预览加水印与禁止下载打开。CI 的采样截图与审核同样适用视频流,审核相关在下一节细讲。 转码费用值得单独算一笔账。我们上线前两个月借了内部历史视频试水,每分钟转码约一分钱,全月转码费约 150 元。把存储类型降低与转码费加一起,仍然远低于让用户自己下载播放的流量费。算账思路是固定的:转码费对比流量费,转码是一次性的,流量是每次下载都收。
| 费用项 | 月度金额 | 备注 |
|---|---|---|
| 视频转码 | 约 150 元 | 按输出时长 |
| 文档转 pdf | 约 60 元 | 按页计费 |
| 转码结果存储 | 约 30 元 | 标准存储 |
| 节省的下载流量 | 约 800 元 | 用户不用整包下 |
转码任务要做优先级管理。管理后台上传的内部视频可以慢慢排,用户当面分享等待的必须插队。我们用两个队列区分优先级,简单粗暴有效。否则高峰期一个两小时录像排在前面,后面用户的演示视频等到地老天荒。
视频的列表封面也可以用 CI 采样截图自动生成。抽三帧存在 cover 前缀下,列表页直接用截图中帧,视频列表的点击率上升明显。用户是视觉动物,封面图比文件名诚实,也更吸引人。
音频类内容也别忘了。传上来的播客录音常是 m4a 或 wav,直接给链接浏览器也能放,但统一转 mp3 兼容性更好。音频转码极快,成本可忽略,全套流程复用媒体任务管道,加一行判断即可。
最后说个预览的边界认知。预览必须永远给出原始下载入口,这是体面也是兜底。转码可能失败、清晰度可能不够、格式可能仍不兼容,把用户困在预览里没法拿到原始文件是耍流氓。我们所有预览页右上角永远有一枚下载按钮,没钱画图标也要画。 再说说预览的用户体验细节。手机上自动播放、电脑上点第一帧播放,两套交互是不同的。移动端对省流量敏感,默认静音小图播放;桌面端直接播。这类差异产品文档要写清楚,多端团队共用一套逻辑必然有一端难用。
清晰度自适应我们用 hls 分片方案。转码时同时输出多档清晰度,播放器按网速自动切换。多档转码费略高但体验跨设备稳定,弱网用户也不至于完全看不了。hls 一开始也踩过切片时长的坑,六秒一切播首帧慢,调成两秒后体感好了一截,参数都是试出来的。
PDF 预览器选型也头疼。浏览器原生 pdf 预览在 Firefox 与 Safari 上有格式兼容问题。最后用 pdf.js 统一渲染,移动端也能看,体积大了首次加载慢但可接受。一个稳定的预览组件顶过半年的修修补补。
文档转码有个硬限制值得提前知道:CI 对特别大的文档(几百页的那种)会限制或拆分处理。我们遇到过一份 800 页的全员手册转不出来,拆成多份才能处理。提前在文档页数超限时不给预览只给下载,至少页面不空白不报错给用户看。
预览数据也值得看。我们统计过带预览的分享链接,平均停留时间是纯下载链接的四倍。视频在线看的转化让网盘的角色从快递柜变成了展厅。功能做到这个份上已经不是技术问题,是产品形态问题。 转码任务的状态管理是看不见的工作量。任务有排队中、处理中、成功、失败四种状态,前端轮询不是好办法但够简单,每三秒查一次,百分之一秒级的延迟换实现简单。任务完成用长连接通知是更优雅的方案,我们的量级还撑不起那份复杂度,先用轮询顶着。
还有一个坑是源文件更新后的转码失效。用户覆盖上传同名文件,旧转码结果 URL 被缓存着,预览还是旧视频。解决方式和图片一样:URL 带版本指纹,转码产物关联源指纹,一变全变。这套设计我们复用了四五处,几乎成了内部组件。
再聊一句外行话。视频预览上线后,产品同学提了个需求:给每个视频加封面描述,让搜索更好用。我直接把 CI 采样截图与文件名解析结合起来,没什么人工就做出了带封面的视频库。功能的衍生价值经常超出最初设想,前提是底层的管道足够通用。
给最后没耐心的同学一句话总结:视频预览 = 转码 + 缓存 + 兜底下载,三件事一件不能少。 对了,移动端的视频预览还有个流量保护:非 Wi-Fi 环境默认给标清,除非用户手动切换。这种小开关用户感知不到,但每月的移动投诉量确实降了。技术同理心,说的就是这种细节。 补充一句对 mp4 输出的参数解释。我们用 h264 编码而不是 h265,尽管 h265 能省四成带宽,但浏览器兼容性仍然成问题,尤其 Safari 与部分国产浏览器。面向团队的工具优先稳定,编码格式选择永远以兼容性为先,其次是体积,最后才是情怀。
另一个细节是视频转码后的元数据要回写文件记录:时长、清晰度、缩略图地址,前端列表展示全部依赖它。少了这些字段,用户只能看到一个孤零零的文件名,产品质感立刻差一截。 转码还需要注意清理。失败的重试任务留下大量中间态文件,我们每周清一次 preview 目录的孤儿对象,别让垃圾悄悄推高存储费。
转码模板我们只选了三档:流畅、高清、超清。档位多了用户选择困难,转码费也翻倍;档位少了覆盖不了网络差异。三档是多次试验后的甜点数,也是成本与体验的平衡点。
文档预览最难的是复杂排版。某些多图表的 PPT 转图片后文字糊掉,我们改用矢量化渲染方案后才恢复清晰。预览体验是内容型产品的生命线,马虎不得。
转码失败的文件要有兜底。我们遇到过原始视频损坏导致转码永远失败,任务重试把队列堵死。加了重试次数上限后,失败转人工查日志,队列再没积压过。
预览能力的覆盖度决定了网盘的产品力。我们从最初的图片预览一路扩展到视频、音频、文档、代码高亮,每加一种格式,用户停留时长就涨一截。预览是文件通往内容的桥。
小结
转码是算力换体验的生意:花一点转码费,换来打开率与停留时长。控制好清晰度与转码触发时机,费用完全可控。预览功能上线后,我们网盘的分享链接有点像正经网盘了,而不是一个 FTP。
