Akagi201
2/20/2017 - 10:24 AM

[移动直播技术分享]

[移动直播技术分享]

###1. 推流端 直播技术的流程大致可以分为几个步骤:数据采集、数据处理、视频编码、封包发送、云端(服务端)(转码、录制、分发)、播放器。

  1. 数据采集:通过摄像头和麦克风获得实时的音视频数据;

  2. 数据处理:将数据采集的输入流进行实时滤镜,得到我们美化之后的音视频数据, 视频包括各种处理滤镜,美颜,动态贴纸等, 音频包括降噪, 放大等处理;

  3. 音视频编码:编码分为软编码和硬编码。现在直播默认的编码都是 H.264。软编码是利用 CPU 进行编码,硬编码就是使用 GPU 进行编码。软编码支持现在所有的系统版本。由于苹果在 iOS8 才开放硬编码的 API,故硬编码只支持 iOS8 以上的系统;

  4. 封包发送:现在直播推流中,一般采用的格式是 FLV , 然后利用 ffmpeg 或者 librtmp 进行传输, 这两者封包的处理是不一样的,我们采用的是 ffmpeg , 所以没有对 librtmp 进行深入的研究;

  5. 云端(服务端):进行流的转码、分发和录制;

  6. 播放器:负责拉流、解码、播放。

  7. 乱谈:杂谈

采集音视频数据

移动端直播采集摄像头,麦克风的数据。

图像采集: 设置一下前置摄像头 后置摄像头. 配置一下采集的参数, 图像数据的长宽, fps, 输出的方向, 横屏竖屏等. 然后从回调中取到数据就行了。

_videoCamera.outputImageOrientation = videoCameraOrientation;
        
// 设置拍摄帧频
_videoCamera.frameRate = _fps;

音频采集: 前期不需要音频数据处理需求的时候, 配置一下音频采集的采样频率, 采样精度, 声道就行了.

        _audioFormat0.mSampleRate       = 44100.00;
        _audioFormat0.mFormatID         = kAudioFormatLinearPCM;
        _audioFormat0.mBitsPerChannel       = 16;

数据处理

如果不需要处理音视频数据的话。 采集这一块是很简单的。只要调用系统的 AVCaptureSession , 拿到音视频数据之后 直接丢给编码器编码就行了。

图像: 不过如果需要 美白, 水印, 裁剪等一些处理效果. 就必须处理拿到的 buffer, 这个时候还要考虑到拿到的数据是 YUV 还是 RGB . iOS 上是不能对 YUV 格式直接进行 美颜处理的。只能是 RGB 格式, 这个算是坑。 所以后来就选择使用了 GPUImage 库. 调用 GPUImage 来进行采集和 美白, 水印, 裁剪的处理, 然后取出来进行编码上传, 另一方面显示在预览画面上。

声音: 增益降噪等, 直接从 speex 项目中抽出来的声音处理代码.然后调用, 处理。 有混音的需求, 类似在直播的时候播放背景音乐. 简单的采集就不行了. 这个时候就需要使用 Audio Unit 来实现音频数据的混音, 而还需要将混音的背景音乐转成 PCM 数据, 拷贝一份送入混音. 原来的数据送入播放器。

硬编码音视频数据

软编码就是利用CPU资源来压缩音视频数据,硬编码与之相反。

软编码: 现在广泛采用FFmpeg库结合编码库来实现,FFmpeg + x264 来编码视频数据YUV/RGB输出H264数据, FFmpeg+fdk_aac 来编码音频数据PCM输出AAC数据。

硬编码: iOS 8之后开放了硬解码和硬编码API, 所以基本上都是选择 VideoToolBoxAudioToolBox 进行图像和音频的硬编码.

封包发送

将音频,视频打包成packet。

因为我们先做的播放器.播放器采用 FFMPEG 进行数据的接收. 推流端也就默认使用了 FFMPEG 进行数据的封包发送。

封包的时候要注意, 编码的数据, 是有 Sps Pps 数据的

云端(服务端)

根据所选流媒体协议,发送相应指令连接服务器,连接服务器成功后,就可以发送packet数据了。 我们用的是 RTMP, 服务端会进行 转码, 录制, 转 HLS 的操作。

播放器

拉流端

拉流,就是从流媒体服务器获取音频,视频数据。

一、解析协议

播放器端根据URL解析所用的流媒体协议(RTMP,HLS)。

二、解封装

解封装,就是demux的过程,从容器格式(FLV,TS)中,分离出音视频数据。

三、解码

解码,就是把获取到的数据解压缩,恢复成原始数据。解码就是将H264变成YUV,AAC变成PCM。

解码可以使用软解码,硬解码。

软解码就是利用CPU资源去解压缩数据,采用的方式是FFmpeg解码。

硬解码,对于iOS平台来说,可以使用VideoToolbox.Framework(该框架只能在iOS 8.0及以上系统使用) 硬解码视频数据。Android平台上,可以使用MediaCodec来硬解码视频数据。

四、渲染数据

采用OpenGL渲染YUV数据,呈现视频画面。将PCM送入设备的硬件资源播放,产生声音。

iOS播放流式音频,使用Audio Queue 的方式,即,利用AudioToolbox.Framework 框架

乱谈

附1: 音频基础知识。

  1. 采样频率: 把每一秒钟所采样的数目称为采样 频率或采率,单位为HZ(赫兹)。 采样频率越高所能描述的声波频率就越高。 采样频率是指录音设备在一秒钟内对声音信号的采样次数,采样频率越高声音的还原就越真实越自然。 采样频率中, 22.05 KHz只能达到FM广播的声音品质,44.1KHz则是理论上的CD音质界限,48KHz则更加精确一些。对于高于48KHz的采样频率人耳已无法辨别出. 因为连麦用的声网的 SDK, 为了兼容编码, 现在推流的音频采样率为 32 kHz.
  2. 采样精度: 采样位数可以理解为采集卡处理声音的解析度. 采集和 播放声音文件时所使用数字声音信号的二进制位数. 8位代表2的8次方--256,16 位则代表2的16次方--64K。比较一下,一段相同的音乐信息,16位声卡能把它分为64K个精度单位进行处理,而8位声卡只能处理256个精度单位, 造成了较大的信号损失.所以 16 位的精度比 8 位进度保真度更高。
  3. 音频数据大小计算: 44.1KHz(采样率) X 16bit(采样精度) X 2(双声道) X 播放时间, 音频处理的时候. 我们不可能把所有的音频直接 进行处理和编码。 降噪 处理长度是 20 ms , iOS 硬编码 AAC 的编码长度固定是 2048.

附2: 图像基础知识。

  1. YUV 分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色. YUV格式有两大类:planar和packed。 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。 对于packed的YUV格式,每个像素点的Y,U,V是连续交叉存储的. YUV 标准的 I420 一帧的大小 size=width×heigth×1.5 Byte

    iOS 上有两种 YUV 存储格式 NV12 和 NV21, 是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储.

  2. RGB 三基色排列, ARGB 或者 BGRA 每个像素用32位表示,RGB分量各使用8位(剩下的8位用于表示Alpha通道值), 一帧的大小 size=width×heigth×4 Byte.

UPLiveSDK 流程图