音视频通信——直播协议和视频推流

HEVCCJL 2019-06-26

近年来直播已成为互联网行业的大热话题,直播答题、游戏直播、竞赛直播等层出不穷,直播早已成为人们耳熟能详的技术。事实上直播的兴起不仅与新时代人们要求为自己代言的心理有关,同时也得益于带宽的提速和CDN技术的发展。伴随着CDN技术的成熟,企业自己部署云服务器做直播也越来越简单

本文作为直播介绍系列文的第2篇,主要和大家谈谈直播协议、视频推流等技术内容

直播协议

流媒体分为直播和点播。通常来说点播使用的都是HTTP协议,直播主要用的是RTMP, HLS, HTTP-FLV等。近年来直播协议也有新发展如DASH,但仍处于起步阶段。

直播和点播协议的不同,根源在于他们的业务差异。点播,常见用于优酷,爱奇艺等视频网站中电视剧、电影等媒体资源的播放,即点播都是录制好的视频,一千个人看同一个视频,无论任何时候点进去获取到的媒体数据都是一样的,而直播则不然,不同时候点进来观看到的信息是不一样的。

通常来讲,直播和点播是相互并不交融的,不过近些年来也有人创新发展——直播时移模式,即点播与直播相结合。其做法是将直播流录制成一小片一小片的点播文件,然后用户可以在任何地点、任意终端访问任意内容。比如你正在看一场球赛的直播,然后有一个镜头很精彩,想马上再看一遍,就可以拖一下进度条回退然后回放,在看完回放后还可以一键返回直播。

目前直播分发主要有以下特点:

1,flv居多,ts较少,原因主要是ts标准太过于复杂。Flv的标准开放文档是11页,ts的有174页。对于一般的直播,flv基本能满足需求,因此ts应用就较少。当然了,我们也可以借助于FFmpeg,但是它会将流媒体方面你想得到的和想不到的都封装了,不够精准。

2,rtmp和hls并存。一般来讲,rtmp用在PC端上,使用flash播放;hls用作手机和平板上。

3,实时流一般使用rtmp。rtmp能做到1到3秒的延迟,是直播里除了rtsp外延迟最低的协议。PC上支持直接播放,移动端可以用FFmpeg解码播放。除了rtmp还有其他协议适合实时流媒体播放吗?

实际上http-flv比rtmp更合适实时流播放。二者延迟一样,在PC端上都可直接播,移动端需要使用ffmpeg,但http-flv还有个好处就是能穿墙。但大多数CDN并不支持http-flv直播,因为一般的Web服务器不支持http-flv,这是个流媒体问题。

直播服务器

直播中流媒体数据的传输主要依赖服务器。目前开源的流媒体服务器,有RED5、CRTMPD、NGINX-RTMP和SRS等

RED5:最古老的基于flash的流媒体服务的开源流媒体服务器。它由Java语言编写,使用rtmp作为流媒体传输协议,与FMS完全兼容;具有流化flv、MP3文件,实时录制客户端流为flv文件,共享对象,实时视频播放、Remoting等功能。但由于其技术较为落后,新入场的直播平台都已放弃使用。

CRTMPD:使用c++语言编写,支持多种rtmp协议、IPTV相关网络协议和移动设备的流媒体服务器。使用单线程异步socket,在当时处于领先水平,但是当NGINX出现后就渐渐淡出大众视野了。

NGINX-RTMP :基于NGINX模块,使用C语言编写的流媒体服务器,也是目前市场上使用最多的流媒体服务器。伴随着2012年CDN业务的扩展,直播业务需求暴涨,由于NGINX-RTMP中直播点播共用一套服务器,且用户熟悉信任NGINX;NGINX-RTMP逐渐处于行业垄断地位。

SRS(Simple Rtmp Sever)是一个国产的流媒体服务器,产品定位是运营级的互联网直播服务器集群,追求更好的概念完整性和最简单实现的代码。据官网介绍其效率非常高,能达到NGINX-RTMP的3倍,而且中英文文档各有一份,较为适合国内程序员的开发环境。

直播推流

直播推流的总体过程如下图

音视频通信——直播协议和视频推流

如上图所示,直播中通常在从摄像头和麦克风等采集到相关数据源后需要做一些封装前处理,如去噪、美颜、变声等,然后进行音视频编码,再用相适应的流媒体协议封装,进行码率自适应后就可投到相关站点展示了。

但是在不同的技术语言下做直播推流的方法也是不同的

如果你是iOS或者Android程序员,做RTMP推流就会更简单,可以直接找一个推流的数据库然后给出视频参数,以及最终的RTMP地址,就能推出一个标准的RTMP流

如果你是C++程序员,会麻烦很多,你至少要掌握采集、编码、写流这3个步骤。当然,这些步骤都有库可以调用,但是即便如此,假设你使用FFmpeg库,完成上述动作代码也需要100行左右了;因为其主要的代码流程就需包括打开音视频设备、创建编解码器、设置编码参数、初始化网络流句柄、写协议头、循环采集数据、解码数据、编码数据、格式封装和写网络流。

当然,你可以直接用FFmpeg的命令行,一条命令完成推流,但是这也仅限于测试或者做简单的demo,真正的工程环境中并不适用,因为这种一条简单命令的方法在许多功能上都不能支持。

总结:

总之,做直播难易程度主要是和你想实现的功能有关,如果你只是打算自己做测试,那下载一个开源服务器代码,编码运行,再用FFmpeg一行命令推流,再用播放器播放也就完成了。但是如果想要商业化,满足用户的多种需求,如回声抑制、连麦直播、美颜滤镜等,问题的复杂度就呈指数倍上涨了。

相关推荐