17611538698
webmaster@21cto.com

HTTP流媒体播放技术发展及Nginx点播源站搭建

资讯 0 2283 2017-04-10 12:00:49



focus-nginx.png

 
21CTO社区导读:音视频内容已经成互联网产品的重要部分,故而流媒体播放优化技术是提升产品体验的关键。本文介绍HTTP流媒体点播技术的演进及点播服务器的处理。希望大家能通过本文中的对比选择合适的技术。


  互联网多媒体内容传输从大方向上可以分为下载传输和流式传输,而流式传输又可以分为顺序流式传输和实时流式传输,换句话来说就是点播(Video on Demand)和直播(Live Streaming)。
  顾名思义,前者的媒体内容是提前存储在服务器上供客户端请求播放,而后者是实时产生并分发给客户端播放。
  本文主要是基于HTTP的流媒体点播技术入门,讲述了一些基本的概念以及这一技术的变革演进。
  互联网上传播音视频内容最早从上世纪90年代开始,RTP等专有协议的提出就是定义音视频的包格式以获得更低的网络传递开销。不过现如今的互联网世界,CDN扮演着非常重要的角色,而绝大部分CDN厂商是不支持RTP等协议的。
  基于HTTP的流媒体点播技术则占据着主流,其有几点优势:
  1、防火墙友好;
  2、客户端控制媒体流的访问,服务端不需要为每一个客户端连接维护媒体session状态;
  3、采用标准的HTTP服务器即可,支撑大规模客户端访问不需要额外的服务器技术资源开销,最重要的就是CDN技术的良好支持优化。
  HTTP的流媒体点播技术演进
  HTTP流媒体技术的变革大致经过了以下四个阶段:
  /uploads/fox/10080600_0.png
  最初,我们只能先下载完整视频文件到本地磁盘后,然后才能播放观赏。这意味着你必须等待视频下载操作的完成,严格来讲,根据我们第一段的划分,这不能称作为流媒体传输,不过我们还是列出来,以作对比。如下图示:
  /uploads/fox/10080600_1.jpeg
  在上面简单下载文件的基础上,一个明显的提升就是渐进式下载技术。这种情况下不需要完整下载视频文件,可以边下载边播放,这就要求视频的元数据信息必须放在视频文件的开头。但是,我们只能在已经下载的那一部分自由拖拽播放,而未下载的部分是不能播放的。如下图所示:
  /uploads/fox/10080600_2.png
  在渐进式下载的基础上,pseudo-streaming(伪流)出现了,其增强了seek播放功能,也就是支持直接切到未下载的地方进行观看,所以也可以称之为渐进式播放。请看下图:
  /uploads/fox/10080600_3.png
  其实,到pseudo-streaming 这一步,流媒体播放的技术已经很成熟了,而且目前绝大多数的视频网站都是这种技术,比如Youtube、优酷等。
  如果要在这基础上再一步优化,可以从哪些方面着手呢?比较容易想到的就是带宽优化,能够链路感知,这就是下面的自适应比特率流。
  其原理就是,同一视频内容会有不同的码率版本,客户端播放器会动态地根据网络质量切换与请求带宽匹配的视频片段。
  /uploads/fox/10080600_4.jpeg
  自适应码率流媒体技术,业内比较常见的实现是Apple的HTTP Live Streaming (HLS)以及Adobe的HTTP Dynamic Streaming (HDS)。
  下图简单展示了HLS的文件结构,可以看到master playlist包含了两种不同码率的播放列表,当然如果你只有一种版本,那么就不需要master playlist了。
  基于HTTP的自适应码率流媒体是有国际标准的,那就是3GPP组织和MPEG小组所提出的MPEG-DASH(Dynamic Adaptive Streaming over HTTP)。
  /uploads/fox/10080600_5.png
  点播流媒体服务器工作原理
  我们来说说一个简单的点播流媒体服务器是怎么工作的。
  目前,很常见的一种搭建方式就是基于Nginx,而Nginx本身对音视频媒体的处理就有一定的支持,官方就有flv和mp4的插件,即ngx_http_flv_module和ngx_http_mp4_module。前者支持以字节偏移的渐进式seek播放,后者支持以时间偏移的渐进式seek播放。
  要想达到这种渐进式播放的目的,大部分情况下,我们是要对服务端的媒体文件进行一定的处理的。首先播放之前,服务端需要先返回一定的视频元数据信息,其次我们需要知道媒体时间和媒体数据的映射关系。
  为什么要对服务端的媒体文件进行一定的处理呢?
  
  目前大部分的视频编码都采用H264标准,而H264的不同视频帧采用了不同的压缩编码方式,其中I帧的作用很大,其通常是每个 GOP(Group of Picture)的第一个帧。我们简单点说,I帧依靠自身就可以解码出完整图像,而其后面帧的解码则需要依赖I帧,这决定了我们在拖拽播放的时候,播放器会seek到最近的I帧处,所以有时候会有一个现象,就是当你拖到一个精确的时间点时,播放器却在另一个靠近的时间点开始播放,这就是因为那个时间点是I帧所在之处。
  播放器的seek播放通常是让用户选择时间偏移,而服务端最终对文件的请求处理只能是字节偏移,所以我们要有一个时间偏移和字节偏移的映射表。严格一点说,是每一个I帧的时间偏移与字节偏移映射。
  那么这个映射是放在客户端还是服务端处理呢?
  ‍
  当然是都可以。如果客户端发出字节偏移请求,那么服务端就很轻松,只需要提供HTTP range访问的功能,但是客户端需要提前知道时间与字节的映射关系,比如flv格式的元数据就提供了这个信息,有的flv文件没有加入元数据,这时候就需要用相应的flv工具(比如flvmeta)去处理成这样的格式,这样客户端的播放器就可以直接发送字节偏移量了。
  MP4则不需要这么处理,因为MP4格式本身就要求带这样的信息,其记录元数据的Movie Box (moov)中的Media Information Box (minf)就存储了媒体时间和媒体数据的映射关系。
  如果客户端只发出时间请求,那么服务端就得将时间偏移请求转换为字节偏移请求,然后处理并响应请求。


  来源:网易云。


评论