直播技术的总结

2022年01月16日 阅读数:3
这篇文章主要向大家介绍直播技术的总结,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

 


1.概述


关于直播的技术文章很多,成体系的很少。咱们将用这篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面、深刻地了解视频直播技术,更好地技术选型。ios


1.1 一个完整的直播APP原理

​直播原理​​ : 把主播录制的视频,推流送到服务器,服务器通过处理(鉴黄等),经过CDN分发给观众看。nginx

​直播环节​​ : 推流端(采集、美颜、编码、推流),服务端处理(转码、录制、截图、鉴黄)、播放器(拉流、解码、渲染)、互动系统(聊天室、礼物系统、赞)git


1.2 一个完整直播APP实现流程

​1.采集、2.滤镜处理、3.编码、4.推流、5.CDN分发、6.拉流、7.解码、8.播放、9.聊天互动​github



直播技术的总结_数据


1.3 一个完整直播APP架构


​1.采集端、服务端、播放端​缓存



1.4 一个完整直播APP技术点


直播技术的总结_ios_02


下面咱们会选择一部分技术进行讲解。服务器


2. 视频采集


2.1 基本知识介绍

​AVFundation​​ : 音视频数据采集须要用AVFundation框架网络

​AVCaptureDevice​​ : 硬件设备,包括麦克风、摄像头、经过该对象能够设置物理设备的一些属性。例如相机焦距,白平衡等session

​AVCaptureDeviceInput​​ : 硬件输入对象,能够根据AVCaptureDevice建立对应的AVCaptureDeviceInput对象,用于管理硬件输入数据架构

​AVCaptureOutput​​ : 硬件输出对象,用于接收各种输出数据,一般使用对应的子类AVCaptureAudioDataOutput(声音数据输出对象), AVCaptureVideoDataOutput(视频输出对象)app

​AVCaptureConnection​​ : 当把一个输入和输出添加到AVCaptureSession后。AVCaptureSession就会在输出、输出设备之间创建链接,并且经过AVCaptureOutput能够得到这个对象

​AVCaptureVideoPreviewLayer​​ : 相机拍摄预览图层,能实时查看相机效果。建立该对象须要指定对应的AVCaptureSession对象,由于AVCaptureSession包含输出数据,有视频数据才能显示。

​AVCaptureSession​​ : 协调输入与输出之间传递数据


2.2 捕获音视频步骤


直播技术的总结_ios_03


步骤:


  1. 建立AVCaptureDevice(video或者audio)
  2. 根据AVCaptureDevice建立AVCaptureDeviceInput。
  3. 建立AVCaptureSession
  4. 把建立的AVCaptureDeviceInput加入AVCaptureSession
  5. 添加视频预览图层AVCaptureVideoPreviewLayer
  6. 建立AVCaptureAudioDataOutput,并加入AVCaptureSession
  7. 启动会话



官方步骤(能够忽略):


  1. 建立AVCaptureSession对象
  2. 获取AVCaptureDevice录像设备(摄像头),录音设备(麦克风)。只用于配置
  3. 根据音频/视频硬件设备(AVCaptureDevice)建立音频/视频硬件输入数据对象(AVCaptureDeviceInput),专门管理数据输入。
  4. 建立视频输出数据管理对象(AVCaptureVideoDataOutput),而且设置样品缓存代理(setSampleBufferDelegate)就能够经过它拿到采集到的视频数据
  5. 建立音频输出数据管理对象(AVCaptureAudioDataOutput),而且设置样品缓存代理(setSampleBufferDelegate)就能够经过它拿到采集到的音频数据
  6. 将数据输入对象AVCaptureDeviceInput、数据输出对象AVCaptureOutput添加到媒体会话管理对象AVCaptureSession中,就会自动让音频输入与输出和视频输入与输出产生链接.
  7. 建立视频预览图层AVCaptureVideoPreviewLayer并指定媒体会话,添加图层到显示容器layer中
  8. 启动AVCaptureSession,只有开启,才会开始输入到输出数据流传输


其中​​AVCaptureAudioDataOutput​​​、​​AVCaptureVideoDataOutput​​包含两个代理方法,能够一直监听捕获属性。

 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
if (self.videoConnection == connection)
{
NSLog(@"采集到视频");
}
else if(self.audioConnection == connection)
{
NSLog(@"采集到音频");
}
}

// 丢失帧会调用这里
- (void)captureOutput:(AVCaptureOutput *)captureOutput didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection NS_AVAILABLE(10_7, 6_0)
{
NSLog(@"丢失帧");
}

 

2.3 捕捉图片

​AVCaptureStillImageOutput​​能够将捕获到的Video转换为图片。


  1. 建立device

  2. 根据device建立deviceInput

  3. 添加deviceInput进session

  4. 添加预览图层

  5. 添加deviceOutput进session

  6. 调用AVCaptureConnection生成图片



2.4 捕捉视频

​AVCaptureMovieFileOutput​​ 能够将捕捉到的视频输出到磁盘。能够设置录制最长时限或录制到特定大小,还能够配置成保留最小可用磁盘空间。


  1. 建立device
  2. 根据device建立deviceInput
  3. 添加deviceInput进session
  4. 添加预览图层
  5. 添加deviceOutput进session
  6. 调用AVCaptureMovieFileOutput把视频写入文件


​AVCaptureMovieFileOutput​​​包含有几个代理方法。分别是​​视频开始录制​​​,​​视频暂停​​​,​​视频恢复​​​, ​​视频将要录制完成​​​, ​​视频录制完成​​。



2.5 采集音频视频按帧输出流程解析


1.找到物理设备摄像头_inputCamera、麦克风_microphone,建立摄像头输入videoInput和麦克风输入audioInput;

2.设置videoInput和audioInput为_captureSession的输入,同时设置videoOutput和audioOutput为_captureSession的输出,而且设置videoOutput和audioOutput的输出delegate;

3._captureSession调用startRunning,开始捕获信号;

4.音频数据到达,把数据转发给以前设置的audioEncodingTarget,并经过调用assetWriterAudioInput的appendSampleBuffer方法写入音频数据;

5.视频数据到达,视频数据传入响应链,通过处理后经过assetWriterPixelBufferInput的appendSampleBuffer方法写入视频数据;

6.选择保存后,文件经过ALAssertLibrary写入手机照片库。



流程图:


直播技术的总结_ide_04

2.6 Demo在这里

代码 : 捕获音视频Demo


3. GPUImage


​前面好像没看懂,能够看这里吗?​

能够,GPUImage对AVFundation进行了一层封装,就算你不会前面的也不要紧。


3.1 基本概念

​GPU​​ 手机或者电脑用于处理图像渲染的硬件

​OpenGL ES​​ 一套图形与硬件接口,用于把处理好的图片显示到屏幕上。

​GPUImage​​ 是一个基于OpenGL ES 2.0图像和视频处理的开源iOS框架,提供各类各样的图像处理滤镜,而且支持照相机和摄像机的实时滤镜,内置120多种滤镜效果,而且可以自定义图像滤镜。

​GPUImage​​ 是一个基于OpenGL ES 2.0图像和视频处理的开源iOS框架,提供各类各样的图像处理滤镜,而且支持照相机和摄像机的实时滤镜,内置120多种滤镜效果,而且可以自定义图像滤镜。

​滤镜处理的原理​​ 就是把静态图片或者视频的每一帧进行图形变换再显示出来。它的本质就是像素点的坐标和颜色变化


3.1 利用GPUImage处理直播过程当中美颜流程

​采集视频 => 获取每一帧图片 => 滤镜处理 => GPUImageView展现​


直播技术的总结_ide_05


3.2 处理画面原理

GPUImage采用链式方式来处理画面,经过addTarget:方法为链条添加每一个环节的对象,处理完一个target,就会把上一个环节处理好的图像数据传递下一个target去处理,称为GPUImage处理链。通常的target能够分为两类:​ ​​中间环节​​的target,通常是指各类filter,是GPUImageFilter或者是子类

​最终环节​​的target,GPUImageView 用于显示到屏幕上或者GPUImageMovieWriter写成视频文件。

主要分为三个环节:​​source(视频,图片源) => filter(滤镜) => final target(处理后的视频、图片)​


3.3 美颜原理

​磨皮(GPUImageBilateralFilter)​​:本质就是让像素点模糊,可使用高斯模糊,可是可能致使边缘会不清晰,用双边滤波(Bilateral Filter) ,有针对性的模糊像素点,能保证边缘不被模糊。

​美白(GPUImageBrightnessFilter)​​:本质就是提升亮度。


3.4 GPUImage源对象

GPUImage的数据源只能是4类:

​GPUImageVideoCamera​​ ios摄像头的实时美颜。GPUImageVideoCamera是GPUImageOutput的子类,提供来自摄像头的图像数据做为源数据,通常是响应链的源头。

​GPUImageStillCamera​​ 相机拍照

​GPUImagePicture​​ 处理静止图像

​GPUImageMovie​​ 电影





3.5 用法


  1. 建立过滤器
  2. 建立源对象
  3. 把过滤器添加到源对象
  4. 生成target


静态图片处理:

 

UIImage *inputImage = [UIImage imageNamed:@"105"];

// 建立过滤器
GPUImageBrightnessFilter *filter = [[GPUImageBrightnessFilter alloc] init];
filter.brightness = 0.5;
[filter forceProcessingAtSize:inputImage.size];
[filter useNextFrameForImageCapture]; // 告诉系统从后来捕获过滤器

// 处理静止的图像
GPUImagePicture *stillPic = [[GPUImagePicture alloc] initWithImage:inputImage];
[stillPic addTarget:filter]; //添加过滤器
[stillPic processImage]; // 执行渲染

UIImage *newImage = [filter imageFromCurrentFramebuffer];

UIImageView *imageView = [[UIImageView alloc] initWithImage:newImage];
[imageView sizeToFit];
[self.view addSubview:imageView];
imageView.center = CGPointMake(CGRectGetWidth(self.view.frame)/2, CGRectGetHeight(self.view.frame)/2);


实时美颜处理:

 

// 建立视频源
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionBack];
// 设置方向
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;

// 建立预览View
GPUImageView *videoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:videoPreview atIndex:0];

// 添加预览图层到源
GPUImageBeautifyFilter *fiter = [[GPUImageBeautifyFilter alloc] init];
[_videoCamera addTarget:fiter];
[fiter addTarget:self.videoPreview];
// 开始采集视频
[videoCamera startCameraCapture];

 


到这里,仅仅是屏幕显示的内容有滤镜效果,而做为直播应用,还须要输出带有美颜效果的视频流。咱们须要使用​ ​​GPUImageMovieWriter​​类,才能处理视频流。


核心思路:

经过GPUImageVideoCamera采集视频和音频信息,音频信息直接发送给​​GPUImageMovieWriter​​​,视频信息传入响应链做为源头,渲染后的视频再写入​​GPUImageMovieWriter​​​,同时经过​​GPUImageView​​​显示在屏幕上。只须要​​addTarget​​​就能够添加​​GPUImageMovieWriter​​;


直播技术的总结_数据_06




4. 音视频编码,解码


VideoToolBox

AudioToolBox



5. 流媒体服务器


国内外有不少好用的流媒体服务区。这里为了方便搭建咱们采用​​nginx+RTMP​​搭建流媒体服务器。


5.1 MAC环境搭建

MACOS上搭建nginx+rtmp环境


5.2 Centos环境搭建

Centos下搭建的nginx + RTMP环境


5.3 服务端经常使用技术

​CDN​​ 直播数据上传到服务器后,观看直播的人比较多,服务器是承受不了的,会将数据分发到CDN,观众直接去CDN获取数据。减小服务器的负载。

​负载均衡​​ 由多台服务器组成一个服务器集群,每次请求的时候,会根据服务器负载选择处理请求的服务器。



6. 推流

6.1 推流协议的选择

HLS和RTMP


6.2 推流原理

在iOS设备上进行各推流的话,是经过AVCaptureSession这么一个捕捉会话,指定两个AVCaptureDevice 也就是iOS的摄像头和麦克风,获取个原始视频和音频,而后须要进行个H.264的视频编码和AAC的音频编码,再将编码后的数据整合成一个音视频包,通 过rmtp推送到nginx服务器


6.3 librtmp

这个参考资料不多。不过大部分都采用的这个。由于涉及太多C/C++这里不讨论。

 



7. 音视频播放

7.1 播放框架的选择

iOS的播放框架主要有如下三种:


  1. AVPlayer 能够播放本地、远程视频,能够自定义UI进行控制
  2. AVPlayerViewController 自带播放控制UI,不能自定义UI
  3. MPMoviePlayerController,MPMoviePlayerViewController (iOS9后弃用)



若是只是简单的播放视频,选择​​AVPlayerViewController​​​,若是想自定义播放器,选择​​AVPlayer​​。


7.2 AVPlayer

AVPlayer是一个用来播放基于时间的流媒体控制对象。支持播放从本地、分布下载或经过HTTP Live Streaming协议获得的流媒体。AVPlayer只管理一个单独资源的播放,不过框架还提供了AVPlayer的一个子类AVQueuePlayer,能够用来管理一个资源队列。当你须要在一个序列中播放多个条目或者为音频、视频资源设置播放循环时可使用该子类。

AVPlayer视频播放使用步骤:


  1. 建立视频资源地址URL,能够是网络URL
  2. 经过URL建立视频内容对象​​AVPlayerItem​​,一个视频对应一个​​AVPlayerItem​
  3. 建立​​AVPlayer​​视频播放对象,须要一个​​AVPlayerItem​​进行初始化
  4. 建立​​AVPlayerLayer​​播放图层对象,添加到现实视图上去
  5. 添加KVO监听。 监听到AVPlayerItemStatusReadyToPlay的时候调用play方法


7.3 AVPlayerViewController

​AVPlayerViewController​​​属于​​AV Kit​​​,它是​​UIViewController的子类​​,用于展现并控制AVPlayer实例的播放。

​AVPlayerViewController​​类使用步骤


  1. 建立URL
  2. 建立AVPlayerViewController,并根据URL设置player属性
  3. 调用play方法

AVPlayerViewController的使用

Xcode8模拟器可能有问题,打开播放不了。



8.开源框架

前面所讲都有第三方框架支持。采集、美颜、推流有​​LFLiveKit​​​, 拉流播放有​​IJKMediaFramework​​。


​LFLiveKit​​ : LFLiveKit是iOS版开源RTMP流SDK。他支持后台录制、美颜功能、支持h26四、AAC硬编码,动态改变速率,RTMP传输等


​IJKMediaFramework​​ : ijkplayer是B站开源的一款视频直播框架,它是基于ffmpeg。 若是从github下载是须要编译。参考地址:http://www.jianshu.com/p/1f06b27b3ac0

我的实验只须要配置Nginx+RTMP服务

这里我采用这两个第三方框架写了一个直播,包含在线观看直播,和直播推流,支持在线美颜,先后摄像头切换等你须要:




  1. 搭建​​Nginx+RTMP环境​​:MAC 或者  Centos

  2. 下载项目真机运行。https://github.com/tiantianlan/miaoboDemo登录界面



直播技术的总结_ios_07









直播技术的总结_ios_08直播技术的总结_数据_09注本公众号,学习 iOS 开发