1. 直播原理
把主播录制的视频,推流到服务器,服务器进行处理(黄鉴等),通过CDN分发给观众看
- 直播环节: 推流端(采集、美颜、编码、推流),服务端处理(转码、录制、截图、鉴黄)、播放器(拉流、解码、渲染)、交互系统(聊天室、礼物系统、赞)
2. 一个完整的直播APP实现流程
1.采集、2.滤镜处理、3.编码、4.推流、5.CDN分发、6.拉流、7.解码、8.播放、9.聊天互动
3. 一个完整的直播APP架构 1.采集端、服务端、播放端
4. 一个完整的直播APP技术点
1.参考链接
直播项目 原理/播放/采集/美颜 技术总结
2.视频采集
2.1 基本知识介绍 AVFundation
音视频数据采集需要用AVFundation框架
- AVCaptureDevice : 硬件设备,包括麦克风、摄像头、通过该对象可以设置物理设备的一些属性。例如相机焦距,白平衡等
- AVCaptureDeviceInput : 硬件输入对象,可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,用于管理硬件输入数据
- AVCaptureOutput : 硬件输出对象,用于接收各类输出数据,通常使用对应的子类AVCaptureAudioDataOutput(声音数据输出对象), AVCaptureVideoDataOutput(视频输出对象)
- AVCaptureConnection : 当把一个输入和输出添加到AVCaptureSession后。AVCaptureSession就会在输入、输出设备之间建立连接,而且通过AVCaptureOutput可以获得这个对象
- AVCaptureVideoPreviewLayer : 相机拍摄预览图层,能实时查看相机效果。创建该对象需要指定对应的AVCaptureSession对象,因为AVCaptureSession包含输出数据,有视频数据才能显示
- AVCaptureSession : 协调输入与输出之间传递数据
2.2 捕获音视频步骤 包含关系
步骤:
- 创建AVCaptureDevice(video或者audio)
- 根据AVCaptureDevice创建AVCaptureDeviceInput
- 创建AVCaptureSession
- 把创建的AVCaptureDeviceInput加入AVCaptureSession
- 添加视频预览图层AVCaptureVideoPreviewLayer
- 创建AVCaptureAudioDataOutput,并加入AVCaptureSession
- 启动会话
官方步骤(可以忽略):
- 创建AVCaptureSession对象
- 获取AVCaptureDevice录像设备(摄像头),录音设备(麦克风)。只用于配置
- 根据音频/视频硬件设备(AVCaptureDevice)创建音频/视频硬件输入数据对象(AVCaptureDeviceInput),专门管理数据输入。
- 创建视频输出数据管理对象(AVCaptureVideoDataOutput),并且设置样品缓存代理(setSampleBufferDelegate)就可以通过它拿到采集到的视频数据
- 创建音频输出数据管理对象(AVCaptureAudioDataOutput),并且设置样品缓存代理(setSampleBufferDelegate)就可以通过它拿到采集到的音频数据
- 将数据输入对象AVCaptureDeviceInput、数据输出对象AVCaptureOutput添加到媒体会话管理对象AVCaptureSession中,就会自动让音频输入与输出和视频输入与输出产生连接.
- 创建视频预览图层AVCaptureVideoPreviewLayer并指定媒体会话,添加图层到显示容器layer中
- 启动AVCaptureSession,只有开启,才会开始输入到输出数据流传输
其中AVCaptureAudioDataOutput、AVCaptureVideoDataOutput包含两个代理方法,可以一直监听捕获属性
不清楚可以查看官方文档:官方文档
2.3 捕捉图片 AVCaptureStillImageOutput可以将捕获到的Video转换为图片
- 创建device
- 根据device创建deviceInput
- 添加deviceInput进session
- 添加预览图层
- 添加deviceOutput进session
- 调用AVCaptureConnection生成图片
2.4 捕捉视频 AVCaptureMovieFileOutput 可以将捕捉到的视频输出到磁盘。可以设置录制最长时限或录制到特定大小,还可以配置成保留最小可用磁盘空间
- 创建device
- 根据device创建deviceInput
- 添加deviceInput进session
- 添加预览图层
- 添加deviceOutput进session
- 调用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写入手机照片库。
2.6 Demo在这里 代码 : 捕获音视频Demo
可以,GPUImage对AVFundation进行了一层封装,就算你不会前面的也没关系
3.1 基本概念 GPU 手机或者电脑用于处理图像渲染的硬件
- OpenGL ES 一套图形与硬件接口,用于把处理好的图片显示到屏幕上。
- GPUImage 是一个基于OpenGL ES 2.0图像和视频处理的开源iOS框架,提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜,内置120多种滤镜效果,并且能够自定义图像滤镜
- 滤镜处理的原理 就是把静态图片或者视频的每一帧进行图形变换再显示出来。它的本质就是像素点的坐标和颜色变化
利用GPUImage处理直播过程中美颜流程 采集视频 => 获取每一帧图片 => 滤镜处理 => GPUImageView展示
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 用法
- 创建过滤器
- 创建源对象
- 把过滤器添加到源对象
- 生成target
静态图片处理:
实时美颜处理:
到这里,仅仅是屏幕显示的内容有滤镜效果,而作为直播应用,还需要输出带有美颜效果的视频流。 我们需要使用GPUImageMovieWriter类,才能处理视频流。
核心思路:
通过GPUImageVideoCamera采集视频和音频信息,音频信息直接发送给GPUImageMovieWriter,视频信息传入响应链作为源头,渲染后的视频再写入GPUImageMovieWriter,同时通过GPUImageView显示在屏幕上。只需要addTarget就可以添加GPUImageMovieWriter;
3.6 实例代码在这里 美颜的使用
6.1 推流协议的选择 HLS和RTMP
6.2 推流原理
在iOS设备上进行推流的话,是通过AVCaptureSession这么一个捕捉会话,指定两个AVCaptureDevice 也就是iOS的摄像头和麦克风,获取个原始视频和音频,然后需要进行H.264的视频编码和AAC的音频编码,再将编码后的数据整合成一个音视频包,通过rmtp推送到nginx服务器
6.3 librtmp 这个参考资料很少。不过大部分都采用的这个。 因为涉及太多C/C++这里不讨论
7.1 播放框架的选择 iOS的播放框架主要有以下三种:
- AVPlayer 可以播放本地、远程视频,可以自定义UI进行控制
- AVPlayerViewController 自带播放控制UI,不能自定义UI
7.2 AVPlayer
AVPlayer是一个用来播放基于时间的流媒体控制对象。支持播放从本地、分布下载或通过HTTP Live Streaming协议得到的流媒体。 AVPlayer只管理一个单独资源的播放,不过框架还提供了AVPlayer的一个子类AVQueuePlayer,可以用来管理一个资源队列。当你需要在一个序列中播放多个条目或者为音频、视频资源设置播放循环时可以使用该子类。
AVPlayer视频播放使用步骤:
- 创建视频资源地址URL,可以是网络URL
- 通过URL创建视频内容对象AVPlayerItem,一个视频对应一个AVPlayerItem
- 创建AVPlayer视频播放对象,需要一个AVPlayerItem进行初始化
- 创建AVPlayerLayer播放图层对象,添加到现实视图上去
- 添加KVO监听。 监听到AVPlayerItemStatusReadyToPlay的时候调用play方法
7.3 AVPlayerViewController
AVPlayerViewController属于AV Kit,它是UIViewController的子类,用于展示并控制AVPlayer实例的播放。
AVPlayerViewController 类使用步骤
- 创建URL
- 创建AVPlayerViewController,并根据URL设置player属性
- 调用play方法
8.开源框架
前面所讲都有第三方框架支持。采集、美颜、推流有LFLiveKit, 拉流播放有IJKMediaframework
- LFLiveKit : LFLiveKit是iOS版开源RTMP流SDK。他支持后台录制、美颜功能、支持h264、AAC硬编码,动态改变速率,RTMP传输等
- IJKMediaframework: ijkplayer是B站开源的一款视频直播框架,它是基于ffmpeg。 如果从github下载是需要编译。参考地址:http://www.jianshu.com/p/1f06b27b3ac0