GPUImage
可以实现的功能(基于GPU)
- 视频合成
- 视频加水印
- 修改图片
- 使用GPUImage拍照
- 录制视频(CMSampleBuffer)
苹果自带的图片处理框架(基于CPU)
- ImageIO
- CoreImage
视频
- 未经过编码的视频,帧数越大,视频文件体积越大,一个像素根据RGB等计算大小,一秒之内需要30帧才能保证肉眼看起来很流畅(1秒16帧基本看不出卡顿)
文件大小一般会在1080 * 720 * 30 * 90 - 通过编码,让视频文件体积减小,一般从以下方面做处理:
- 空间冗余
- 时间冗余
- 指定编码标准的组织:
- ITU(国际电传视讯联盟)
- H.26X系列(H261,H263,H264/MPEG-4(
最流行
))
- H.26X系列(H261,H263,H264/MPEG-4(
- ISO(国际标准化组织)
- MPEG系列(MPEG-1、MPEG-2、MPEG-4)
- ITU(国际电传视讯联盟)
- 其它:AMV、VP6、VP7、VP8、VP9、WMV
视频编码流程
H264中的三种帧(每一个画面基于三种帧进行编码)
I、B、P帧
编辑方式
- 编码方式有两种:
- 硬编码:使用非CPU进行编码(如GPU、专用的DSP、FPGA、ASIC芯片等)
- 软编码:使用CPU进行编码,软编码通常使用:FFmpeg+x264
- FFmpeg:是一套开源的、用于对音频进行编码、解码、转化计算机程序
- x264:是一种免费、开源、具有优秀算法的H.264/MPEG-4 AVC视频压缩编码方式
- 对比:
- 硬编码:性能高,对CPU没有压力,对其他硬件要求高(如GPU等)
- 软编码:实现直接、简单、参数调整方便,升级易,但CPU负载重,性能不如硬编码
- iOS中编码方式:
- iOS8之前,苹果未开放硬编码接口,只能采用FFmpeg+264--->软编码
- iOS8之后,苹果开放硬编码接口,封装ViewToolBox和AudioToolBox两个框架,分别针对音频和视频进行硬编码
视频推流
协议
- HLS
苹果公司推出。基于http的拉流协议。原理:将完整视频切片(例如,将MP4文件切换成m3u8和ts切片),客户端依次下载切片进行播放。- 先切片,后传输,因此传输会延迟,
不适合用做直播
。 - 可以通过FFmpeg实现切片。
- 命令: ffmpeg -i xxx.mp4 -c:v libx264 -c:a copy -f hls xxx.m3u8
- m3u8索引头解析
- 先切片,后传输,因此传输会延迟,
EXTM3U -------------------------------- m3u文件头,必须放在第一行
EXT-X-MEDIA-SEQUENCE -------- 第一个TS分片序号
EXT-X-TARGETDURATION -------- 每个分片TS最大时长
EXT-X-ALLOW-CACHE ------------- 是否允许cache
EXT-X-ENDLIST ----------------------- m3u8文件结束符
EXTINF ----------------------------------- extra,info,分片ts信息(如时长、带宽等)
- RTMP
Adobe公司推出。基于TCP的推流协议。是目前的主流协议。本质是流协议。主要优势:- 实时性高。在3s内,经过多层CDN界面分发,实时性也在三秒左右。
- 支持加密。支持RTMPE和RTMPS协议。
- 稳定性高。
使用:
RTMP会对传输的数据进行格式化,称为RTMP message。
为了更好的实现多路复用、分包、信息公平性,发送端会把message划分为带有messageID的chunk,每个chunk可能是一个单独的message,也可能是message的一部分,接收端会根据message中data的长度、messageID、message的长度,把chunk还原成完整的message,实现信息的收发。
本地推流
- Nginx安装
// 克隆到本地
brew tap homebrew/nginx
// unlink
brew unlink nginx
// 安装
brew install nginx-full --with-rtmp-module
// 启动
nginx
macOS系统,安装配置文件路径是:/usr/local/etc/nginx/nginx.conf
- 配置nginx支持hls:
在默认配置:
location / {
root html;
index index.html index.htm;
}
平级添加:
location /hls {
#Serve HLS config
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/var/www;
add_header Cache-Control no-cache;
}
- 配置nginx支持RTMP:
在最外层,和http平级添加:
rtmp {
server {
listen 1935;
application rtmplive {
live on;
max_connections 1024;
}
application hls {
live on;
hls on;
hls_path /usr/local/var/www/hls;
hls_fragment 1s;
}
}
}
- 配置完成,需要重启nginx生效。
nginx -s reload
遇到过的报错:
- rtmp安装不正确,看上方安装步骤。
nginx: [emerg] unknown directive "rtmp" in /usr/local/etc/nginx/nginx.conf:134
- 端口被占用报错:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
解决方案:
// 根据端口号查看进程号
sudo lsof -i :8080
// 杀死进程
kill -9 进程号
// 启动
nginx
iOS实现直播
使用第三方库
OC使用LFLiveKit
swift使用HaishinKit