视频编解码的理论和实践1:基础知识介绍

近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术。因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术。   相关阅读推荐 《视频直播关键技术:流畅、拥塞和延时追赶》 《视频直播技术详解:直播的推流调度》 《音视频通话:小议音频处理与压缩技术》   1、视频介绍 视频的本质是图像序列,根据视觉暂留的原理,每秒播放20~25张图像,就会形成连续平滑的视觉效果,人眼将无法区分其中单幅的图像,就这样连续的画面叫做视频。每秒播放的图像数量叫作帧率。图像是由像素构成的,在彩色图像中,每个像素由R、G、B三个分量构成,每个分量用一个字节存储。分辨率用于描述图像的尺寸,例如分辨率1280x720就表示图像宽度是1280个像素、高度是720个像素。   2、压缩视频的原因 为什么要对视频进行压缩?假如有一段时长为60秒视频,它的分辨率是1280x720,帧率是25,那么这段视频的大小等于:60 x 25 x 1280 x 720 x 3 = 4147200000字节,大约是3955MB,如此庞大的数据,如果不进行压缩,那么磁盘空间将会很快被占满。 多媒体数据占了互联网数据量的80%以上,其中大部分都是图像视频数据,未压缩之前的视频非常庞大,不利于存储和传输,因此很有必要对视频进行压缩,视频压缩也叫作视频编码,它利用视频中存在的空间冗余和时间冗余,剔除人眼不敏感的信息,达到数据压缩的目的。 3、视频压缩的依据 视频能够进行压缩的根本原因是信息冗余,视频中存在两种冗余信息: 空间冗余。对于视频的每一帧图像,在一定尺度范围内,像素的变化是非常平缓的,像素之间非常相似,这就是空间冗余。 时间冗余。视频是由连续变化的图像构成的,在一个很短的时间内,相邻图像之间的变化很小,因此相邻图像很相似,这就是时间冗余。   4、视频编码的原理和细节 由于视频中存在大量的信息冗余,想要对视频进行压缩,就必须找到去除冗余信息的方法,标准的视频编码过程包含下面几个步骤: 预测编码。所谓预测就是利用前面像素值来推算当前的像素值。根据前面的知识我们知道,在空间或者时间上相邻的像素是很相似,因此只要预测方法合适,预测值和实际值会很接近,假设当前像素的实际值是X,预测值是P,那么X和P之间的残差A=X-P。如果我们只对残差数据进行编码,那么将会大大压缩数据量。这就是预测编码的原理。预测编码可以分为空间预测(帧内预测)和时间预测(帧间预测)两种。预测编码可以分为下面几个步骤: 利用前面已经编码并重构像素块预测当前像素块的值 求当前像素和预测像素的差值 对像素差值进行编码 把编码后的数据传输到解码端,在解码端按照同样的方法对像素值进行预测,再加上残差,就可以重构得到原始图像了。 为了得到最佳的预测值,编码器通常需要使用不同预测方法进行预测,然后根据某个评判标准(一般是SAD、STAD、RDO等)得到最优的预测值(注意不是预测值越接近实际值就越优,所谓最优是计算复杂度、失真和码率之间的综合考量),特别对于帧间预测来说,在预测的时候要在参考帧中找到当前块的匹配块,需要大量的计算,因此预测模块一般是编码器中计算量最大的模块,而预测方法的好坏也直接决定了视频的压缩率。 变换编码。变化编码本身不会对数据进行压缩,变换的目的是把空域信息转换为频域信息,去除了信息之间的相关性,在接下来的编码操作中可以得到更高的压缩比,变化编码是为下一步的量化编码做准备的。在视频编码中常见的变换方法是DCT变换和哈达玛变换。 量化编码。量化是视频产生失真的根本原因。经过预测编码、变换编码之后得到的数据被称为变换系数,虽然变换系数相对于原始数据数来说已经很小了,但是系数值的变化范围仍然很大,利用量化把变换系数的连续取值转换成有限的离散值,这样可大大提高压缩率。假设有这样一组数据[16,96,100,600,50],量化参数是25,那么量化之后数据是round([16 / 25, 96 / 25, 100 / 24, 600 / 25, 50 / 25])= [0,4,4,24,2],可以看到,量化之前的数据范围是16~600,需要大量的比特数才能表示,量化之后的数据范围是0~24,只需要少量比特数就可以表示,实现了压缩数据的目的。编码是一个不可逆的操作,它是失真产生的根本原因。 环路滤波。环路滤波和压缩没有很大关系,却和视频的画面质量有很大关系。视频编码是以块为单位进行的,在经过量化模块时,可能每个块选择的量化系数不同,导致每个块产生的失真不一样,造成像素块的边界不连续,因此人眼观看视频的时会有方块效应(也就是有很多马赛克现象)。为了提高视频质量,有必要对方块效应进行消除,这就是环路滤波模块的功能。经过量化操作之后的数据块,再经过反量化、反变换,然后进行重构,接着进入去方块滤波进行去方块操作,得到的像素块就可以作为参考像素块给预测模块使用。环路滤波是一个可选模块。 熵编码。熵编码的目的是去除统计冗余,实现数据的进一步压缩。这么说可能有点抽象,举个例子,假设有这样一组数据[0,4,4,24,2],如果使用定长编码来进行编码,这段数据可以表示为[00000,00100,00100,11000,00010],每个数据需要5bit来表示,这段数据的总长度是5 bit x 5=25 bit;如果我们使用哈夫曼来编码,这个数组中每个元素概率值分别如下:数值0的概率是20%,数值4的概率是40%,数值24的概率是20%,数值2的概率是20%,即[20%,40%,20%,20%],根据每个元素的概率构造哈夫曼树(节点中括号内的是数组元素值),如下图所示,因此这段数据可以表示为[0,10,110,111],数据的总长度是11 bit。     由此可见使用哈夫曼编码可以去除统计冗余,实现数据压缩的目的,哈夫曼编码就是一种熵编码方法,但是由于哈夫曼编码对错误非常敏感,不适合实际应用,因此实际应用中通常使用变长编码(CAVLC)和算术编码(CABAC)作为熵编码算法。算术编码利用一个0到1之间的浮点数来描述一个信号序列,然后用这个浮点数来表示这个信号序列,极大的压缩了数据。算术编码可以使用一个简单的例子说明,假设有一个二进制串“10101110”,符号0和1的概率值都是50%,算术编码的过程如下: 设置定一个区间,通常这个区间我们设定为[0,1),然后使用low指向区间的下界,用high指向区间的上界,现在low指向0,rhigh指向1. 输入每一个符号,按照符号的不同对low和high进行调整,调整方法如下面公式所示,最后把low指向的浮点数作为这个符号串的码字,表示这个二进制串,可以看到算术编码的压缩效率比哈夫曼编码高很多,在x264中使用CABAC(上下文自适应的二进制算数编码)作为熵编码算法。     以上就是编解码技术的基础知识介绍,该系列第二篇文章将会介绍视频编解码技术的实践。  

2018-09-18

短视频技术详解:Android端的短视频开发技术

在 《如何快速实现移动端短视频功能?》中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务。在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术。   推荐阅读 《视频私有云实战:基于Docker构建点播私有云平台》 《如何快速实现移动端短视频功能?》   短视频业务主要包含:“视频录制”以及 “视频编辑”这两个核心功能。 其中视频录制又包括:视频采集、实时美颜、自定义码率、摄像头切换、变焦、对焦、曝光度调节以及滤镜等功能。 视频编辑包括:视频裁剪、视频拼接、混音、视频动画效果、动态贴图等功能。 Android端短视频录制的技术方案 我们先来说说视频录制:   视频录制的大致实现流程就如上图所示,先由Camera、AudioRecord进行最原始的相机画面以及声音的采集,然后将采集的数据进行滤镜、降噪等前处理,处理完成后由MediaCodec进行硬件编码,最后采用MediaMuxer生成最终的MP4文件。 这个方案的优点在于,由于全程采用了GPU以及硬件编码,基本上不涉及CPU上的操作,因此可实现在高帧率(30fps)、高分辨率(720P)以及高码率的情况下CPU暂用率也非常低,即使在性能较差的手机上也能很好的运行。但同时这个方案的难点也在于此。 做过音视频的同学都知道,通常情况下我们所说的对音视频的处理,主要是对视频的 YUV、H264 音频的PCM、AAC这类数据格式进行操作,这类操作都有相关的RFC技术也比较成熟,实现起来比较容易,出了问题也更容易定位,通常情况下在PC等设备上也都是这么处理的。 但这样的方案在对于手机端情况就不同了,虽然手机这几年的性能大大加强了,很多旗舰手机基本都是8核的CPU了,但要操作如此大量的图片数据并进行浮点运算对CPU的消耗还是很大的。CPU暂用率高就会引起手机发烫,手机发烫就会导致Camera采集的掉帧,甚至在一些小米等厂商下,手机发烫还会引起CPU降频,CPU一降频那APP所暂用的CPU比例就更高了,同时CPU暂用率高电量消耗就快。 因此上面的方案是目前Android上比较适合短视频录制的方案。 Android端短视频录制的具体实现 既然确定了技术方案,我们就来看看具体的实现。这里首先需要知道几个概念: SurfaceTexture 我们知道在一些简单的自定义相机应用中,要实现一个相机,只需要将一个SurfaceHolder设置给Camera,Android系统就会自动的帮我们把Camera采集的数据绘制到屏幕上。但由于在短视频中我们需要对相机采集的数据进行前处理加工比如滤镜等,而且还要做到可见即所得的效果,因此必须要求我们将相机采集的数据先缓存起来,前处理完后自己再绘制到屏幕上,这时候就需要用到SurfaceTexture了。按照Android官方文档的介绍,SurfaceTexture就是这样一块用于接收Camera采集的数据,同时又不可见的画布。这块画布是存在于GPU内存中的。 TextureID 纹理ID,主要用来标识每一块纹理在GPU内存中的内存地址,类似于C语言中的内存指针。每一块GPU的纹理(可以理解为一块用于显示图片的画布)都有对应的一个TextureID进行标识。上述的SurfaceTexture在创建也同样需要绑定一个纹理ID进行唯一标识。     知道了这两个概念,我们就知道了Camera采集的数据具体存在于GPU的哪个位置了。接下来就可以对原始的数据进行前处理编码了。 这里有一个需要注意的地方,Android的camera采集到SurfaceTexture上的纹理是GL_TEXTURE_EXTERNAL_OES 类型的纹理,而目前市面的很多滤镜算法,如开源的GPUImage中很多的滤镜都是基于GL_TEXTURE_2D类型的纹理进行图像处理的。 因此在进行我们在基于开源滤镜算法或自研算法时需要先将GL_TEXTURE_EXTERNAL_OES类型的纹理转化为GL_TEXTURE_2D的纹理,或者在GPU Shader中加入 "#extension GL_OES_EGL_image_external: require"  来表明该纹理是OES纹理,同时编写基于OES纹理的图像处理算法。 目前网易这边是先将OES转化为TEXTURE_2D在进行前处理,这样便于与iOS端算法统一以及更好的接入一些开源的滤镜算法。 解决了SurfaceTexture的问题,接下来的MediaCodec以及MediaMuxer就比较容易了。Android中的MediaCodec天生支持将GPU中的纹理绘制到MediaCodec的Surface中,然后对Surface中的图像直接进行硬件编码,图像数据始终是在GPU空间中进行流转,而没有涉及到CPU。 这里需要注意的是MediaCodec以及MediaMuxer需要在API 18及以上才能使用。同时需要注意MediaCodec在不同设备上的兼容性。 Android端视频编辑功能 最后对于视频编辑的功能,目前Android上没有很好的系统API即硬件处理方式,主要还是利用ffmpeg进行相应的叠加、裁剪混音等后期处理。可以优化的一个点是,先将原始的MP4视频进行解码,然后将解码后的YUV数据映射到GPU的纹理上进行亮度、饱和度等参数的调节,做到文件编辑的所见即所得,然后将调好的参数配置为ffmpeg进行编辑处理。   想要获取更多产品干货、技术干货,记得关注网易云信博客。  

2018-09-18

视频直播技术详解:直播的推流调度

作为直播传输的第一步,推流调度对于直播链路的影响非常大。本篇文章将针对这个话题,从传输的角度,讲一讲网易云信直播是如何做好推流调度的。 推荐阅读 《视频私有云实战:基于Docker构建点播私有云平台》 《如何快速实现移动端短视频功能?》   直播推流是什么 首先,直播推流,即主播将自己的本地客户端采集编码后的视频数据“推”出去。推流会涉及到两个问题:视频推到哪里去了以及观众从哪里将流拉到播放端观看。 主播推流是推到了直播接流服务器,由接流服务器负责分发到更高一层的传输层去将视频流推往全球的观众处。直播接流服务器是视频流从客户端出发后的第一站,也是对传输质量影响最大的一站。直播上行调度处理的问题就是给推流客户端选取一个合适的接流服务器。 直播接流服务器的调度和部署 直播接流服务器的调度和部署大有讲究: 首先,国内由于网络运营商的复杂性,存在众多运营商,小运营商借大运营网络等各种问题。对直播上行调度来说,第一步的挑战就是需要识别出客户具体的地域和网络类型。这一步通常是通过一个网络IP库来处理。虽然网络上存在着各种各样的IP网络库,但准确性并无法保证。网易云信基于20年的互联网经验,积累了大量的IP信息,拥有自己的IP库,相对于网络上通用的IP库能更精准地识别出各地区及运营商问题。 其次,则是调度本身了,即按客户的来源,分配给推流端对应的接流服务器。最常见的系统,是基于DNS的调度。网易云信当然也支持这种调度方式。即给定一个域名,通过网易的DNS权威服务器解析,按照相应的规则,结合客户的运营商和地域信息,分配对应运营商和相近地域的接流服务器给推流客户端。比如,杭州的用户使用域名xx.live.126.net推流,在不考虑DNS缓存的情况下,它会先走到DNS服务器进行域名解析,网易的DNS权威服务器会最终接到这个解析请求,并按IP库查出的对应地区和运营商,给予一个合适的接流服务器的IP地址,返回给客户端。客户端的推流即可以推到这台接流服务器了。 DNS系统是个通用的解决方案,优点即不需要额外的环节介入,直接基于DNS即可实现调度。但它的缺点也相当突出:DNS系统为性能考虑,做了缓存。如果某台接流服务器由于各种原因宕机不可用了,而客户端还会通过缓存取到这台机器作为接流服务器,这样会导致客户端推流不可用。客户端就需要等到对应的DNS缓存失效后,才能使用业务,而这个缓存的失效时间也很复杂,国内的运营商可能会对DNS缓存做额外的延长,这时直播业务可用性就无法保证了。另一方面,DNS系统看到的“客户IP”并不一定是客户视频流出口的IP,而是本地DNS出口的IP,这可能会导致一些DNS系统的误判。 网易云信如何做好推流调度 网易云信拥有自己的直播调度系统。当用户使用网易云信直播SDK进行直播时,SDK会联系网易云信的调度系统直接获取接流服务器地址。由于网易云信调度系统部署选取了多线BGP,与众多小运营商之间都拉了专线,因此小运营商用户在联系网易云调度系统时,不会走第三方大运营商的出口,而是直接走专线出口,这样可以最大程度上降低调度系统对于用户网络运营商的误判。网易云信调度系统在海外也会有对应的调度节点存在,即在海外,客户端同样可以取到合适的接流服务器地址。 另一方面,网易云信的调度系统与全球各边缘上行接流服务器之间有着紧密的联络,会实时监控各接流服务器的实时CPU、内存、网络等资源使用状况,从而最终给出一个最合理的调度结果。 网易云信的用户,可以通过使用网易视频SDK而跳过上述DNS可能存在的问题,而进行更精确的调度,得到更佳的直播体验。 直播系统的上行调度,很大程度上影响着整个直播的质量。如果上行接流服务器调度的不够好,比如客户端运营商识别错误导致客户端将视频流进行了跨运营商的传输,那么网络就很容易不稳定而产生网顿等现象。网易云信直播服务通过以上各种手段,最大程度保证了调度的准确性。   想要获取更多产品干货、技术干货,记得关注网易云信博客。    

2018-09-18

短视频技术详解:Android端的短视频开发技术

在 《如何快速实现移动端短视频功能?》中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务。在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术。   推荐阅读 《视频私有云实战:基于Docker构建点播私有云平台》 《如何快速实现移动端短视频功能?》   短视频业务主要包含:“视频录制”以及 “视频编辑”这两个核心功能。 其中视频录制又包括:视频采集、实时美颜、自定义码率、摄像头切换、变焦、对焦、曝光度调节以及滤镜等功能。 视频编辑包括:视频裁剪、视频拼接、混音、视频动画效果、动态贴图等功能。 Android端短视频录制的技术方案 我们先来说说视频录制:   视频录制的大致实现流程就如上图所示,先由Camera、AudioRecord进行最原始的相机画面以及声音的采集,然后将采集的数据进行滤镜、降噪等前处理,处理完成后由MediaCodec进行硬件编码,最后采用MediaMuxer生成最终的MP4文件。 这个方案的优点在于,由于全程采用了GPU以及硬件编码,基本上不涉及CPU上的操作,因此可实现在高帧率(30fps)、高分辨率(720P)以及高码率的情况下CPU暂用率也非常低,即使在性能较差的手机上也能很好的运行。但同时这个方案的难点也在于此。 做过音视频的同学都知道,通常情况下我们所说的对音视频的处理,主要是对视频的 YUV、H264 音频的PCM、AAC这类数据格式进行操作,这类操作都有相关的RFC技术也比较成熟,实现起来比较容易,出了问题也更容易定位,通常情况下在PC等设备上也都是这么处理的。 但这样的方案在对于手机端情况就不同了,虽然手机这几年的性能大大加强了,很多旗舰手机基本都是8核的CPU了,但要操作如此大量的图片数据并进行浮点运算对CPU的消耗还是很大的。CPU暂用率高就会引起手机发烫,手机发烫就会导致Camera采集的掉帧,甚至在一些小米等厂商下,手机发烫还会引起CPU降频,CPU一降频那APP所暂用的CPU比例就更高了,同时CPU暂用率高电量消耗就快。 因此上面的方案是目前Android上比较适合短视频录制的方案。 Android端短视频录制的具体实现 既然确定了技术方案,我们就来看看具体的实现。这里首先需要知道几个概念: SurfaceTexture 我们知道在一些简单的自定义相机应用中,要实现一个相机,只需要将一个SurfaceHolder设置给Camera,Android系统就会自动的帮我们把Camera采集的数据绘制到屏幕上。但由于在短视频中我们需要对相机采集的数据进行前处理加工比如滤镜等,而且还要做到可见即所得的效果,因此必须要求我们将相机采集的数据先缓存起来,前处理完后自己再绘制到屏幕上,这时候就需要用到SurfaceTexture了。按照Android官方文档的介绍,SurfaceTexture就是这样一块用于接收Camera采集的数据,同时又不可见的画布。这块画布是存在于GPU内存中的。 TextureID 纹理ID,主要用来标识每一块纹理在GPU内存中的内存地址,类似于C语言中的内存指针。每一块GPU的纹理(可以理解为一块用于显示图片的画布)都有对应的一个TextureID进行标识。上述的SurfaceTexture在创建也同样需要绑定一个纹理ID进行唯一标识。     知道了这两个概念,我们就知道了Camera采集的数据具体存在于GPU的哪个位置了。接下来就可以对原始的数据进行前处理编码了。 这里有一个需要注意的地方,Android的camera采集到SurfaceTexture上的纹理是GL_TEXTURE_EXTERNAL_OES 类型的纹理,而目前市面的很多滤镜算法,如开源的GPUImage中很多的滤镜都是基于GL_TEXTURE_2D类型的纹理进行图像处理的。 因此在进行我们在基于开源滤镜算法或自研算法时需要先将GL_TEXTURE_EXTERNAL_OES类型的纹理转化为GL_TEXTURE_2D的纹理,或者在GPU Shader中加入 "#extension GL_OES_EGL_image_external: require"  来表明该纹理是OES纹理,同时编写基于OES纹理的图像处理算法。 目前网易这边是先将OES转化为TEXTURE_2D在进行前处理,这样便于与iOS端算法统一以及更好的接入一些开源的滤镜算法。 解决了SurfaceTexture的问题,接下来的MediaCodec以及MediaMuxer就比较容易了。Android中的MediaCodec天生支持将GPU中的纹理绘制到MediaCodec的Surface中,然后对Surface中的图像直接进行硬件编码,图像数据始终是在GPU空间中进行流转,而没有涉及到CPU。 这里需要注意的是MediaCodec以及MediaMuxer需要在API 18及以上才能使用。同时需要注意MediaCodec在不同设备上的兼容性。 Android端视频编辑功能 最后对于视频编辑的功能,目前Android上没有很好的系统API即硬件处理方式,主要还是利用ffmpeg进行相应的叠加、裁剪混音等后期处理。可以优化的一个点是,先将原始的MP4视频进行解码,然后将解码后的YUV数据映射到GPU的纹理上进行亮度、饱和度等参数的调节,做到文件编辑的所见即所得,然后将调好的参数配置为ffmpeg进行编辑处理。   想要获取更多产品干货、技术干货,记得关注网易云信博客。  

2018-09-18

直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控

线上服务的有效监控和数据收集,一直是后端服务离不开的话题。直播作为一种经典的分布式系统,监控以及数据收集更是必不可少的工作。如何对海量的服务集群有效的监控和保活,又如何抓取集群中的碎片数据中来优化服务?网易云信音视频研发工程师将和大家共同探讨。   推荐阅读 视频私有云实战:基于Docker构建点播私有云平台 高清音质背后:网易云信音乐教学方案技术解密   机器站在巨人的肩膀上用着轮子 作为分布式集群,物理层上的最小单位自然是机器。对于一台机器而言,常规性能指标自然就是CPU、内存、网卡的使用情况。这些性能有很多方式去获取,而视频云采用的是网易的哨兵系统。哨兵系统是网易的监控系统,提供了非常详细和即时的性能指标。 借由哨兵这个强大的轮子,我们能非常方便的在机器级别上,做出有效的监控。例如当网卡流量或者cpu异常的时候,可以快速的报警采取处理。当然,不光光可以监控机器是否能正常运行,也可以监控是否被恶意攻击,这个暂且不谈。   性能指标与业务融合 当然,只有机器级的数据,是远远不够的。俗话说,不与业务贴合的数据,不是好数据。作为直播CDN服务,最常规的参数,自然是音视频码率和延迟。 细心的看官们可能发现了几个比较特殊的统计。 为什么统计了总码率也统计了音视频单独的码率? 这是因为在真实的场景中,总码率并不一定能还原出我们需要的场景,有很多情况会需要单独的分析音视频码率,例如用户主动关闭了视频输出或者机器采样性能不足导致的视频卡顿,这个时候只需要配合帧率的统计,就可以快速还原场景。当然,视频码率本身也不是一个固定的数值。视频云也针对弱网提供QoS(即可变码率)的功能。 推送延迟push_delay是什么? 推送延迟,是一个衡量C/S之间网络情况的参数。当这个参数发生波动的时候,则说明C端的包到达S的时间比预计要长。能够反映出网络的抖动情况。如果计算这个数值呢?简单来说,是使用了RTMP包头部的时间戳。如果非要用一个公式解释一下,我觉得应该是: Delay=abs( (当前RTMP包的到达时间-上个RTMP包的到达时间) – (当前RTMP包的时间戳–上个RTMP包的时间戳) ) 计算每个包到达服务器所消耗时间的差异值,用于代表网络的抖动。当然,还需要做其他很多事情,例如加权和jitter算法来减少误差和避免。 为什么还有send_kbps? 其实这也挺好理解,因为CDN本身是分布式系统,在节点和节点间需要做路径选择,然后从节点到节点传输,从而实现加速。Send_kbps其实就是前一个节点向后一个节点的发送码率。那么这就涉及到了一个问题,如果去trace某一条流的数据呢?对于每一条流,我们会给予一个唯一的标记,在节点间传递的时候,我们会给流添加一个自增的标记Hops。 通过这个标记,可以精准的找到这条流在节点件的走向,从而把各个节点的数据聚合在一起 其他,我们还会抓取一些类似源IP,用户设备等客户端的信息。这些信息能帮忙我们走进大数据时代。   整体数据服务的架构 分布式系统中,每一个节点都会产生大量的统计和性能数据。所以在视频云,有一个完整的统计架构来作出支持。从最前端的数据采集、传输,到汇总,然后到计算集群,最后输出。每一个服务都各司其职。让我们来看看整体架构。 对于每一个区域,会有一个数据汇聚的服务器,负责从流媒体服务器收集数据。最初的元数据,经过数据汇聚服务器汇总、过滤和压缩以后。统一上报到中心集群中的统计服务器。统计服务器会将所有的统计数据,逐一落库,储存在数据仓库中。其余的数据计算集群,会从数据仓库中定时进行读取计算。具体的计算间隔,会根据业务类型不同而不同。例如运维平台会主要读取一些机器级别的数据,进行分析和报警。大数据计算集群则会对数据进行计算,得出优化方向,此处我们稍后再聊。业务数据展示平台则是会实时的输出数据(例如码率和延迟),用于提供给用户和技术支持查询。当然,还有其他各种各样的数据处理服务,这里就不再一一介绍。   数据能做的一些事情 最后,我们聊一聊数据。在这个大数据时代,有了数据却不做事情,等同于浪费。那么,有了这些数据以后,我们做了什么事情呢?当然,最显而易见的,就是调整调度策略,增设布点。例如,上图的大数据的运算结果,南京电信的网络权重比较差,这就说明南京电信地区需要进行排查。而南京移动的用户量较大,也说明南京地区应该增设服务点。 此外,数据和性能指标的上报,也会被用于均衡负载调度。例如某一个节点压力较大的时候,或者性能不稳定的时候,这个节点的调度优先级就会被降低(即不太会被优先分配给用户)。 以上就是我对于直播CDN服务监控的一些看法,但是直播CDN服务监控和数据收集是一个值得无止境讨论和优化的事情,欢迎大家留言与我探讨。 想要获取更多产品干货、技术干货,欢迎关注网易云信博客。     云信介绍参考: 网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通信与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者通过集成客户端SDK和云端OPEN API,即可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。  

2018-09-18

音视频通话:小议音频处理与压缩技术

在视频或者音频通话过程中,一方面为了减小原始声音数据的传输码率,需要进行音频压缩,另一方面为了得到更高质量的音质,需要进行音频处理。那么,如何处理好这两方面,保证声音传播的高真性?本篇文章将会结合网易云信在音视频技术方面的实战和经验,小议音频处理与压缩技术。   推荐阅读: 《视频私有云实战:基于Docker构建点播私有云平台》 《高清音质背后:网易云信音乐教学方案技术解密》   音频处理的方法主要包括:音频降噪、自动增益控制、回声抑制、静音检测和生成舒适噪声,主要的应用场景是视频或者音频通话领域。音频压缩包括各种音频编码标准,涵盖ITU制定的电信领域音频压缩标准(G.7xx系列)和微软、Google、苹果、杜比等公司制定的互联网领域的音频压缩标准。(iLBC、SILK、OPUS、AAC、AC3等)。   音频基础概念 在进一步了解音频处理和压缩之前需要知道这些: (1)音调:泛指声音的频率信息,人耳的主观感受为声音的低沉(低音)或者尖锐(高音)。 (2)响度:声音的强弱。 (3)采样率:声音信息在由模拟信号转化为数字信号过程中的精确程度,采样率越高,声音信息保留的越多。 (4)采样精度:声音信息在由模拟信号转化为数字信号过程中,表示每一个采样点所需要的字节数,一般为16bit(双字节)表示一个采样点。 (5)声道数:相关的几路声音数量,常见的如单声道、双声道、5.1声道。 (6)音频帧长:音频处理或者压缩所操作的一段音频信息,常见的是10ms,20ms,30ms。   音频处理基础 噪声抑制(Noise Suppression) 手机等设备采集的原始声音往往包含了背景噪声,影响听众的主观体验,降低音频压缩效率。以Google著名的开源框架WebRTC为例,我们对其中的噪声抑制算法进行严谨的测试,发现该算法可以对白噪声和有色噪声进行良好的抑制。满足视频或者语音通话的要求。 其他常见的噪声抑制算法如开源项目Speex包含的噪声抑制算法,也有较好的效果,该算法适用范围较WebRTC的噪声抑制算法更加广泛,可以在任意采样率下使用。 回声消除(Acoustic EchoCanceller) 在视频或者音频通话过程中,本地的声音传输到对端播放之后,声音会被对端的麦克风采集,混合着对端人声一起传输到本地播放,这样本地播放的声音包含了本地原来采集的声音,造成主观感觉听到了自己的回声。 回声产生的原理如下图所示: 以WebRTC为例,其中的回声抑制模块建议移动设备采用运算量较小的AECM算法,该算法的处理步骤如下图所示。有兴趣的读者可以参考AECM的源代码进行研究,这里不展开介绍了。 自动增益控制(Auto Gain Control) 手机等设备采集的音频数据往往有时候响度偏高,有时候响度偏低,造成声音忽大忽小,影响听众的主观感受。自动增益控制算法根据预先配置的参数对输入声音进行正向/负向调节,使得输出的声音适宜人耳的主观感受。 以WebRTC为例,它的自动增益控制算法的基本流程图如下所示。 静音检测(Voice ActivityDetection) 静音检测的基本原理:计算音频的功率谱密度,如果功率谱密度小于阈值则认为是静音,否则认为是声音。静音检测广泛应用于音频编码、AGC、AECM等。 舒适噪声产生(ComfortableNoiseGeneration) 舒适噪声产生的基本原理:根据噪声的功率谱密度,人为构造噪声。广泛适用于音频编解码器。在编码端计算静音时的白噪声功率谱密度,将静音时段和功率谱密度信息编码。在解码端,根据时间信息和功率谱密度信息,重建随机白噪声。 它的应用场景:完全静音时,为了创造舒适的通话体验,在音频后处理阶段添加随机白噪声。 音频编码基础 音频的另一个广泛应用的领域:音频编码。 首先看一下当前应用最广泛的一些音频编码标准,如下图所示。 图中横轴是音频编码码率,纵轴是音频频带信息。从图中我们可以获得如下几方面信息。 (1)对于固定码率的编码标准,如G.711或者G.722,图中采用单点表示,说明这两个编码标准是固定码率编码标准。其他如Opus、Speex,它们的曲线是连续的,说明这类编码标准是可变码率的编码标准。 (2)从频带方面看,G.711、G.722、AMR和iLBC等标准适用于narrowband(8khz采样率)和wideband(16khz采样率)范围,针对普通的语音通话场景。AAC和MP3适用于fullband(48khz采样率)范围,针对特殊的音乐场景。而Opus适用于整个频带,可以进行最大范围的动态调节,适用范围最广。 (3)从标准的收费情况看,适用于互联网传输的iLBC、Speex和Opus都是免费且开源的;适用于音乐场景的MP3和AAC,需要license授权,而且不开源。   随着音频处理和压缩技术的不断发展,效果更好、适用范围更广、性能更高的算法和新的技术必将不断涌现,如果你有好的技术或者分享,欢迎留言,我们一起探讨。 想要获取更多产品干货、技术干货,欢迎关注网易云信博客。     云信介绍参考: 网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通信与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者通过集成客户端SDK和云端OPEN API,即可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。

2018-09-18

视频直播技术详解:直播的推流调度

作为直播传输的第一步,推流调度对于直播链路的影响非常大。本篇文章将针对这个话题,从传输的角度,讲一讲网易云信直播是如何做好推流调度的。 推荐阅读 《视频私有云实战:基于Docker构建点播私有云平台》 《如何快速实现移动端短视频功能?》   直播推流是什么 首先,直播推流,即主播将自己的本地客户端采集编码后的视频数据“推”出去。推流会涉及到两个问题:视频推到哪里去了以及观众从哪里将流拉到播放端观看。 主播推流是推到了直播接流服务器,由接流服务器负责分发到更高一层的传输层去将视频流推往全球的观众处。直播接流服务器是视频流从客户端出发后的第一站,也是对传输质量影响最大的一站。直播上行调度处理的问题就是给推流客户端选取一个合适的接流服务器。 直播接流服务器的调度和部署 直播接流服务器的调度和部署大有讲究: 首先,国内由于网络运营商的复杂性,存在众多运营商,小运营商借大运营网络等各种问题。对直播上行调度来说,第一步的挑战就是需要识别出客户具体的地域和网络类型。这一步通常是通过一个网络IP库来处理。虽然网络上存在着各种各样的IP网络库,但准确性并无法保证。网易云信基于20年的互联网经验,积累了大量的IP信息,拥有自己的IP库,相对于网络上通用的IP库能更精准地识别出各地区及运营商问题。 其次,则是调度本身了,即按客户的来源,分配给推流端对应的接流服务器。最常见的系统,是基于DNS的调度。网易云信当然也支持这种调度方式。即给定一个域名,通过网易的DNS权威服务器解析,按照相应的规则,结合客户的运营商和地域信息,分配对应运营商和相近地域的接流服务器给推流客户端。比如,杭州的用户使用域名xx.live.126.net推流,在不考虑DNS缓存的情况下,它会先走到DNS服务器进行域名解析,网易的DNS权威服务器会最终接到这个解析请求,并按IP库查出的对应地区和运营商,给予一个合适的接流服务器的IP地址,返回给客户端。客户端的推流即可以推到这台接流服务器了。 DNS系统是个通用的解决方案,优点即不需要额外的环节介入,直接基于DNS即可实现调度。但它的缺点也相当突出:DNS系统为性能考虑,做了缓存。如果某台接流服务器由于各种原因宕机不可用了,而客户端还会通过缓存取到这台机器作为接流服务器,这样会导致客户端推流不可用。客户端就需要等到对应的DNS缓存失效后,才能使用业务,而这个缓存的失效时间也很复杂,国内的运营商可能会对DNS缓存做额外的延长,这时直播业务可用性就无法保证了。另一方面,DNS系统看到的“客户IP”并不一定是客户视频流出口的IP,而是本地DNS出口的IP,这可能会导致一些DNS系统的误判。 网易云信如何做好推流调度 网易云信拥有自己的直播调度系统。当用户使用网易云信直播SDK进行直播时,SDK会联系网易云信的调度系统直接获取接流服务器地址。由于网易云信调度系统部署选取了多线BGP,与众多小运营商之间都拉了专线,因此小运营商用户在联系网易云调度系统时,不会走第三方大运营商的出口,而是直接走专线出口,这样可以最大程度上降低调度系统对于用户网络运营商的误判。网易云信调度系统在海外也会有对应的调度节点存在,即在海外,客户端同样可以取到合适的接流服务器地址。 另一方面,网易云信的调度系统与全球各边缘上行接流服务器之间有着紧密的联络,会实时监控各接流服务器的实时CPU、内存、网络等资源使用状况,从而最终给出一个最合理的调度结果。 网易云信的用户,可以通过使用网易视频SDK而跳过上述DNS可能存在的问题,而进行更精确的调度,得到更佳的直播体验。 直播系统的上行调度,很大程度上影响着整个直播的质量。如果上行接流服务器调度的不够好,比如客户端运营商识别错误导致客户端将视频流进行了跨运营商的传输,那么网络就很容易不稳定而产生网顿等现象。网易云信直播服务通过以上各种手段,最大程度保证了调度的准确性。   想要获取更多产品干货、技术干货,记得关注网易云信博客。    

2018-09-18

直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控

线上服务的有效监控和数据收集,一直是后端服务离不开的话题。直播作为一种经典的分布式系统,监控以及数据收集更是必不可少的工作。如何对海量的服务集群有效的监控和保活,又如何抓取集群中的碎片数据中来优化服务?网易云信音视频研发工程师将和大家共同探讨。   推荐阅读 视频私有云实战:基于Docker构建点播私有云平台 高清音质背后:网易云信音乐教学方案技术解密   机器站在巨人的肩膀上用着轮子 作为分布式集群,物理层上的最小单位自然是机器。对于一台机器而言,常规性能指标自然就是CPU、内存、网卡的使用情况。这些性能有很多方式去获取,而视频云采用的是网易的哨兵系统。哨兵系统是网易的监控系统,提供了非常详细和即时的性能指标。 借由哨兵这个强大的轮子,我们能非常方便的在机器级别上,做出有效的监控。例如当网卡流量或者cpu异常的时候,可以快速的报警采取处理。当然,不光光可以监控机器是否能正常运行,也可以监控是否被恶意攻击,这个暂且不谈。   性能指标与业务融合 当然,只有机器级的数据,是远远不够的。俗话说,不与业务贴合的数据,不是好数据。作为直播CDN服务,最常规的参数,自然是音视频码率和延迟。 细心的看官们可能发现了几个比较特殊的统计。 为什么统计了总码率也统计了音视频单独的码率? 这是因为在真实的场景中,总码率并不一定能还原出我们需要的场景,有很多情况会需要单独的分析音视频码率,例如用户主动关闭了视频输出或者机器采样性能不足导致的视频卡顿,这个时候只需要配合帧率的统计,就可以快速还原场景。当然,视频码率本身也不是一个固定的数值。视频云也针对弱网提供QoS(即可变码率)的功能。 推送延迟push_delay是什么? 推送延迟,是一个衡量C/S之间网络情况的参数。当这个参数发生波动的时候,则说明C端的包到达S的时间比预计要长。能够反映出网络的抖动情况。如果计算这个数值呢?简单来说,是使用了RTMP包头部的时间戳。如果非要用一个公式解释一下,我觉得应该是: Delay=abs( (当前RTMP包的到达时间-上个RTMP包的到达时间) – (当前RTMP包的时间戳–上个RTMP包的时间戳) ) 计算每个包到达服务器所消耗时间的差异值,用于代表网络的抖动。当然,还需要做其他很多事情,例如加权和jitter算法来减少误差和避免。 为什么还有send_kbps? 其实这也挺好理解,因为CDN本身是分布式系统,在节点和节点间需要做路径选择,然后从节点到节点传输,从而实现加速。Send_kbps其实就是前一个节点向后一个节点的发送码率。那么这就涉及到了一个问题,如果去trace某一条流的数据呢?对于每一条流,我们会给予一个唯一的标记,在节点间传递的时候,我们会给流添加一个自增的标记Hops。 通过这个标记,可以精准的找到这条流在节点件的走向,从而把各个节点的数据聚合在一起 其他,我们还会抓取一些类似源IP,用户设备等客户端的信息。这些信息能帮忙我们走进大数据时代。   整体数据服务的架构 分布式系统中,每一个节点都会产生大量的统计和性能数据。所以在视频云,有一个完整的统计架构来作出支持。从最前端的数据采集、传输,到汇总,然后到计算集群,最后输出。每一个服务都各司其职。让我们来看看整体架构。 对于每一个区域,会有一个数据汇聚的服务器,负责从流媒体服务器收集数据。最初的元数据,经过数据汇聚服务器汇总、过滤和压缩以后。统一上报到中心集群中的统计服务器。统计服务器会将所有的统计数据,逐一落库,储存在数据仓库中。其余的数据计算集群,会从数据仓库中定时进行读取计算。具体的计算间隔,会根据业务类型不同而不同。例如运维平台会主要读取一些机器级别的数据,进行分析和报警。大数据计算集群则会对数据进行计算,得出优化方向,此处我们稍后再聊。业务数据展示平台则是会实时的输出数据(例如码率和延迟),用于提供给用户和技术支持查询。当然,还有其他各种各样的数据处理服务,这里就不再一一介绍。   数据能做的一些事情 最后,我们聊一聊数据。在这个大数据时代,有了数据却不做事情,等同于浪费。那么,有了这些数据以后,我们做了什么事情呢?当然,最显而易见的,就是调整调度策略,增设布点。例如,上图的大数据的运算结果,南京电信的网络权重比较差,这就说明南京电信地区需要进行排查。而南京移动的用户量较大,也说明南京地区应该增设服务点。 此外,数据和性能指标的上报,也会被用于均衡负载调度。例如某一个节点压力较大的时候,或者性能不稳定的时候,这个节点的调度优先级就会被降低(即不太会被优先分配给用户)。 以上就是我对于直播CDN服务监控的一些看法,但是直播CDN服务监控和数据收集是一个值得无止境讨论和优化的事情,欢迎大家留言与我探讨。 想要获取更多产品干货、技术干货,欢迎关注网易云信博客。    

2018-09-18

Web屏幕共享插件发布流程

点击链接https://chrome.google.com/webstore/developer/dashboard/进入google开发者控制台,你会看到下图,提示支付5美元开发者注册费。请参考开发者上传插件到Chrome APP Store 流程介绍。 在输入信用卡信息环节,注意选香港,然后再地址中加上“转大陆”字样就可以。 注册开发者身份成功后,将CRX文件打包提交。 发布成功后效果如下图。 点击修改按钮,可以修改插件显示在应用商店的图标,详细说明,屏幕截图,宣传图块等内容 修改相关内容后,可预览修改的内容,确认无误后,点击发布,在Chrome 应用商店中的展示样式如下图所示,则插件发布成功。  

2018-09-18

Chrome屏幕共享功能接入指南

Web端屏幕共享的应用场景众多,如: 在线课堂,老师分享桌面教学课件; 在线会议,与会者全屏分享会议内容; 在线医疗,医生分析患者电子病例; 为了有效解决用户的这些痛点,网易云信工程师已经支持Chrome浏览器下的屏幕共享功能。本文主要谈谈为了实现Web端屏幕共享功能,网易云信WebRTC 工程师,开发者,用户需要做哪些事。 网易云信工程师——Have Done 网易云信工程师采用Chrome插件的形式,将屏幕共享功能集成到自研的WebRTC SDK 中,提供功能完善的Chrome插件、简洁的API接口,详细的说明文档,方便开发者迅速集成Web端屏幕共享功能。目前网易云信WebRTC SDK4.1.0版本已经支持Chrome浏览器的屏幕共享功能,试用于 Chrome 浏览器58.0以上版本。 开发者——To Do 开发者如果在自己的应用中集成Web端屏幕共享功能,要做的事情有: 获取网易云信屏幕共享插件; 发布开发者专属的屏幕共享插件; 获取屏幕共享插件 ID; 部署代码,集成Web屏幕共享功能; 下面简要介绍各个环节。 1、获取网易云信屏幕共享插件 开发者在自己的应用中集成Web端屏幕共享功能,请先去云信官网下载Chrome 屏幕共享插件,插件文件夹的目录结构如图所示: 2、发布专属的屏幕共享插件 在发布自己的屏幕共享插件ID之前,打开获取到的网易云信屏幕共享文件夹,将manifest. json 文件打开。 然后将 match 行的域名替换为开发者的网页域名。 请将获取到的云信Chrome 屏幕共享插件文件,且已经修改为自己的域名的文件夹打包,上传到 Chrome应用商店。请参考Web端屏幕共享插件发布介绍。其目的为:获取屏幕共享插件ID,将该插件ID通过接口传递给网易云信WebRTC SDK ; 3、获取屏幕共享插件 ID 在Chrome应用商店中成功屏幕共享插件后,开发者在应用商店获屏幕共享插件(请确定自己的网络可以正常访问Chrome应用商店) 点击+添加至CHROME,安装屏幕共享插件ID。 点击添加扩展程序安装屏幕共享插件,当Chrome浏览器器的工具栏右上角显示屏幕共享插件logo图标,则下载安装完成,用户可以用Chrome浏览器端的屏幕共享功能。 屏幕共享插件安装完成之后,在 Chrome 浏览器窗口查看插件 ID,该插件ID在集成Web屏幕共享应用时用到。打开 Chrome 浏览器右上角,点击屏幕右上方的扩展按钮,选择 『更多工具』-『扩展程序』,可以看到已经安装完的屏幕共享插件,获取插件ID。   4、部署代码,集成Web屏幕共享功能 开发者在自己的应用中集成Web屏幕共享功能,主要代码如下: 具体代码部署请下载参考网易云信Web教育demo源码。 用户(屏幕共享发起者)——To Do 开发者在Chrome应用商店成功发布自己设计的屏幕共享插件后,且在自己的应用中集成了屏幕共享功能,应用发布后,用户需要做的事情是,下载安装屏幕共享插件。下载安装的方式主要有两种,分为在Chrome应用商店和在开发者自己的网页上下载安装,下文分别介绍。 方式一、从Chrome应用商店下载安装 在Chrome应用商店中成功发布屏幕共享插件后,开发者或者用户都可以在应用商店获屏幕共享插件(请确定自己的网络可以正常访问Chrome应用商店) 点击+添加至CHROME,安装屏幕共享插件ID。 点击添加扩展程序安装屏幕共享插件,当Chrome浏览器器的工具栏右上角显示屏幕共享插件logo图标,则下载安装完成,用户可以用Chrome浏览器端的屏幕共享功能。 方式二、从开发者自己的网页上下载安装 如果用户不能正常访问Chrome应用商店获取插件,开发者可将自己的插件上传到用户可以访问的一个服务器上,用户获取到屏幕共享插件,手动安装插件,主要流程如下: 打开 Chrome 浏览器右上角,点击屏幕右上方的扩展按钮,选择 『更多工具』-『扩展程序』 将获取的屏幕共享插件文件夹拖拽到此窗口。 当Chrome浏览器的工具栏右上角显示屏幕共享插件logo图标,则下载安装完成,则可以使用Chrome浏览器端的屏幕共享功能。

2018-09-18