随着移动开发中的直播越来越火爆,移动开发人员很多都来研究直播技术,深入了解就会明白,直播后面做的事情是非常复杂的,所以对技术要求是非常高的,当然本文不会讲的很深入,因为在下不才,技术很一般,我们只讲直播的基本流程以方便大家理解,直播总体分为2个大体流程:采集端将采集到的音视频数据通过推流地址推送到服务器,播放端再通过拉流地址将音视频数据拉到本地播放。涉及到3各方面:采集端(实时录制)、服务器(处理视频)、播放端(播放视频):
采集端
-音频采集
-视频采集
-音频编码压缩
-视频编码压缩
服务器
-数据分发CDN
-截屏:显示主播画面(第一帧预览图片)
-录制视频
-实时转码
播放端
-从FLV,TS中分离音视频数据
-音视频解码
-播放
作为移动端开发人员其中涉及到的技术点如下图所示:
作为iOS开发人员,对于服务器的处理可以不用管,采集和播放是iOS要做的,主要涉及到以下技术要点:
采集端技术
-AVFoundation框架:数据采集
-GPUImage框架:美颜处理
-FFmoeg框架:音频压缩
-libremp框架:推流
-服务器
-SNS
-BMS
-nginx
播放端技术
-ijkplayer框架:音视频播放
-FFmpeg框架:视频解码
-VideoToolbox框架:视频硬解码
-AudioToolbox框架:音频硬解码
推流
-RTMP
拉流
-FLV
-RTMP
-HLS
这里很有必要解释下,我们这里的播放和采集不是我们自己写的,当然我这样的菜鸟是写不出来的,但是已经有牛逼的大神写好了框架供我们使用,像采集端可以使用LFLiveKit,github地址:https://github.com/LaiFengiOS/LFLiveKit,这个框架里面自己写好了采集视频和推流过程,并且支持很多种的滤镜美颜功能,方便开发者使用,播放视频可以使用ijkplayer,是基于FFmpeg的跨平台播放器框架,由B站开发,目前已被多个主流直播App集成使用,像著名的斗鱼直播,当然了 这里不讲这2个牛逼框架的代码,因为很多都是纯C语言编写的,我们只负责使用大神暴露给我们的接口。
因为我们的视频音频数据是要在服务器进行处理的,所以我们讲一下如何在自己电脑上搭建nginx 服务器(rtmp+ffmpeg框架):
安装Homebrew
打开终端, 查看是否已经安装了Homebrew, 直接终端输入命令
man brew
如果安装成功,会出现很多提示帮助信息,此时输入Q退出即可,反之输入:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
等待一会,让它完成安装
安装nginx服务器
终端输入:
brew tap homebrew/nginx
如果上面的命令被废弃了,就使用下面的命令:
brew tap denji/homebrew-nginx
接着输入:
brew install nginx-full --with-rtmp-module
如下图:
nginx就安装成功了 ,接着输入:
nginx
打开任意浏览器输入地址启动nginx服务器:
[http://localhost:8080](http://localhost:8080/)
如果出现如下界面,nginx服务器就在你本机上安装成功了:
如果出现端口占用问题, 输入:
lsof -i tcp:8080
根据端口PID, kill掉(这儿的9603换成你自己8080端口的PID)
kill XXXX
然后重新输入nginx 打开网址看是否启动成功.
配置nginx和rtmp
查看nginxan安装位置,输入:
brew info nginx-full
如图, 找到nginx.conf文件所在位置:
赋值如下路径, command + shift + G 然后command + V 进入这个nginx.conf文件位置,使用文本编辑打开,鼠标划到最下面,添加下面代码:
# 在http节点后面加上rtmp配置:
rtmp {
server {
listen 1935;
application rtmplive {
live on;
record off;
}
}
}
接着重启nginx,输入
/usr/local/Cellar/nginx-full/1.12.1/bin/nginx -s reload
这里的1.1.1是nginx版本号.可以使用 nginx -v查看并替换
安装ffmpeg
进入终端输入以下命令:
brew install ffmpeg
这里需要等待一会,网速不好的情况下建议翻墙,这个东东只有50多M,不会很久,请耐心等待.
如下图:
至此nginx + rtmp +ffmpeg已经搭建好了:
我们可以使用命令行推一个小视频试试看,进入终端输入:
ffmpeg -re -i 视频路径 -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/rtmplive/room
比如: ffmpeg -re -i /Users/soung1314/Desktop/test.mp4 -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/rtmplive/room
如下所示:
出现以上界面说明推流成功,可以使用VLC测试打开 rtmp://localhost:1935/rtmplive/room并play就会出现刚才推到服务器上的视频,在同一局域网下可以将localhost替换成服务器电脑的那个IP地址,录制推流和试用ijkplayer播放都是基于这一个地址.
这里介绍一下集成ijkplayer打包静态库的打包过程:
首先下载ijkplayer: https://github.com/Bilibili/ijkplayer
进入终端 cd 到ijkplayer-mater文件夹,执行命令
./init-ios.sh
这一步是下载ffmpeg,接着cd 到ios目录,输入:
./compile-ffmpeg.sh clean
然后输入:
./compile-ffmpeg.sh all
接着打包framework:
打开ijkmediaplayer.codePro这个工程,在framework那里点击edit Scheme,在build Configration那里选择Release 然后点击close 然后command + b编译一波,在products那里点击show in Finder,可以看到真机和模拟器两个版本的编译结果 一个是release-iPhones(真机) 一个是release-iPhonesiumulator (模拟器版本)然后 开始合并 在终端里面执行
lipo -create "真机版本路径" "模拟器版本路径" -output "合并后的文件路径"
至此你已经生成了一个framework,就是这个文件,可以直接拖入进你自己的项目中,并build一下,如果没报错,#import
_player = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:url]
withOptions:[IJKFFOptions optionsByDefault]];
_player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_player.view.frame = self.contentView.bounds;
_player.scalingMode = IJKMPMovieScalingModeAspectFill;
_player.shouldAutoplay = YES;
[_player addObserver:self forKeyPath:@"playbackState" options:NSKeyValueObservingOptionNew context:nil];
self.contentView.autoresizesSubviews = YES;
[self.contentView addSubview:_player.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateDidChange:) name:IJKMPMoviePlayerPlaybackStateDidChangeNotification object:_player];
[_player prepareToPlay];
采集推流
这里我们使用的是LFLiveKit这个牛逼的框架:https://github.com/LaiFengiOS/LFLiveKit,clone到本地,在LFLivePreview,m文件的最后面修改为
- (UIButton *)startLiveButton {
if (!_startLiveButton) {
_startLiveButton = [UIButton new];
_startLiveButton.size = CGSizeMake(self.width - 60, 44);
_startLiveButton.left = 30;
_startLiveButton.bottom = self.height - 50;
_startLiveButton.layer.cornerRadius = _startLiveButton.height/2;
[_startLiveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[_startLiveButton.titleLabel setFont:[UIFont systemFontOfSize:16]];
[_startLiveButton setTitle:@"开始直播" forState:UIControlStateNormal];
[_startLiveButton setBackgroundColor:[UIColor colorWithRed:50 green:32 blue:245 alpha:1]];
_startLiveButton.exclusiveTouch = YES;
__weak typeof(self) _self = self;
[_startLiveButton addBlockForControlEvents:UIControlEventTouchUpInside block:^(id sender) {
_self.startLiveButton.selected = !_self.startLiveButton.selected;
if (_self.startLiveButton.selected) {
[_self.startLiveButton setTitle:@"结束直播" forState:UIControlStateNormal];
LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
stream.url = @"rtmp://live.hkstv.hk.lxdns.com:1935/live/stream153";
[_self.session startLive:stream];
} else {
[_self.startLiveButton setTitle:@"开始直播" forState:UIControlStateNormal];
[_self.session stopLive];
}
}];
}
return _startLiveButton;
}
只要将nginx服务器的地址换为你自己搭建的nginx服务器地址即可(localhost改为自己电脑的ip地址), stream.url改为你自己的nginx服务器地址,配合VLC播放器就可以模拟直播采集和播放了
当然我们这里讲的只是基础流程,便于初学者更好的理解直播,由于本人技术有限,如果有写的不好的地方,望不吝赐教,如果您觉着对您理解直播有帮助,请伸出您宝贵的双手star我一波!
作者---mrChan1234