互联网技术的世界很奇怪。

大部分时候我们都会听到各种关于技术更新换代太快的说法,仿佛昨天大家都还在用这个流行的物件(技术、框架、架构等)呢,今天就一窝蜂的追赶上另一个更新更时髦的了。

但有时候又会情不自禁的感慨,有些过时的东西,淘汰的也太慢了。

这些东西,你明知道它们早晚要被淘汰,但你就是不知道它们到底会撑到什么时候。

举个例子,mp4 点播服务的伪流化(pseudo-streaming)功能。

这个功能是干什么的呢,简单描述一下,就是提供了对在线 mp4 点播服务的拖拽功能,或者称为seek。

在 HTML5 流行之前,web 上的视频播放,是 Adobe Flash 的天下。这个时候,mp4 点播服务的伪流化大概是这样的:Flash 播放器会将一次拖拽操作,变成一个带着 start、end 参数的请求发给服务端,服务端根据传入的 start、end 参数和原始 mp4 文件的 moov 数据,生成一个新的 mp4 封装发给播放器。除了 mp4,其他封装的视频格式比如 flv,大概也是如此。

互联网上的视频点播服务诞生了多久,这种技术就用了多久。掐指一算,十几年是有的了。

根据上面的描述,可以看到,伪流化功能主要是在服务端实现的,比如 Nginx 的 ngx_http_mp4_module 模块。非官方的还有一个 nginx_mod_h264_streaming 模块,使用 Nginx 提供 mp4 服务的,八九不离十就是在这两个模块上面改。其他 web server,比如 lighttpd,也是类似。

我们可以并且应该思考一下,这个功能如果放在播放器上来做会怎样呢?这个功能只需要客户端能拿到原始 moov 和根据计算之后的偏移量指定的数据即可。你一定想到了,http range 不就是干这个的吗?

事实却是如此,一些客户端播放器,比如 VLC,正是这么实现拖拽的。

但是在 web 上,就没这么简单了,因为这个领域事实上的标准是 Adobe Flash Player。所以流行的web server 不管愿意不愿意,都要去兼容 Flash Player 的行为,在服务端实现伪流化。

随着 HTML5 开始流行,事情才开始不一样了。mp4 的播放和伪流化,变成了一个浏览器内置的功能。不难想象,伪流化这一部分,仍是基于 http range。这种场景下,服务器上的原始视频文件只要提供静态文件服务并且支持 range 请求就行了。

多美好的事情。况且现在连flv都有 flv.js 这种在浏览器上不依赖 Adobe Flash Player 的开源方案了。

但是如果恰好是一个 CDN 服务商,你会发现,在点播服务上等到 HTML5 普及,还不知道要等到猴年马月呢。

可能你会问了,用 Adobe Flash Player 播放器的,就沿用以前的方案不就 OK 了吗,没什么好纠结的啊?问题在于其他领域的技术都在不断更新,而独这一块维持不变的话,就会引入一些额外的不必要的工作。

比如说缓存服务。不管你用的是哪种 cache server(squid、ats等),要实现一遍 cache 中的 mp4 伪流化吧?

而现在分片缓存流行了(譬如 nginx 的 slice module),又要让你的 cache server 中的 mp4 伪流化支持分片缓存的场景吧?

我个人也是在一年多以前就实现了这个功能,当时 Nginx 的 slice 分片模块还没出来多久。现在看来这个功能应该是 CDN 服务的标配了。

但这确实是个必然要被淘汰的东西啊。想到这里,还真令人惆怅。