闲来无事,自己在空余时间学了一下直播开发。刚开始以为很难,但是当自己做的时候发现很简单,关键是有别人写好的框架。
我看了别人写的一些直播原理,自己也是看得云里雾里的。直播简单来说分为3个模块,第一个模块为录制视频,传输视频到服务器;第二个模块为服务器对传来的视频数据进行编码,转换成你播放视频所支持的网络格式。第三个模块为客户端对服务器进行数据获取并播放。(注意:这里这些只是我自己所述,可能有误,欢迎大神指点)
在编写代码前,我们需要用cocoapods将我们需要的库导入 pod'LFLiveKit'。这里还有一个IJK的库是在cocoapods里面找不到的,所以我们需要自己下载,在最后会附上demo,demo里面有IJKMediaFramework的包,直接拉进工程就行了。
1、布局UI,UI布局这就不说了,我的布局很简单,就3个button,一个label。(图片上中间还有一个button,只不过我用了镂空白色的照片,而且截图是截取模拟器的,没有显示照相机的效果,所以看不到。真机测试是有的)
2、录制视频,传输至服务器
在ViewController先导入头文件#import<AVFoundation/AVFoundation.h> 和 #import"LFLiveKit.h" ,遵循代理LFLiveSessionDelegate
在viewDidLoad里面获取摄像头的权限
//block内部调用self,需要__weak防止循环引用
__weaktypeof(self) _self =self;
//判断用户是否确定授权
AVAuthorizationStatus status = [AVCaptureDeviceauthorizationStatusForMediaType:AVMediaTypeVideo];
switch(status) {
//用户未选择是否确定
case AVAuthorizationStatusNotDetermined:{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted) {
dispatch_async(dispatch_get_main_queue(),^{
[_self.sessionsetRunning:YES];
});
}
}];
break;
}
//用户已经确定授权
case AVAuthorizationStatusAuthorized:
[_self.sessionsetRunning:YES];
break;
case AVAuthorizationStatusDenied:
case AVAuthorizationStatusRestricted:
break;
default:
break;
初始化LFLiveSession类
-(LFLiveSession*)session{
if(!_session) {
_session= [[LFLiveSession alloc]initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration]videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
_session.running=YES;
_session.preView=self.view;
_session.delegate=self;
_session.showDebugInfo=NO;
}
return_session;
}
实现开始直播的button方法
-(void)startAction:(UIButton*)sender{
//定义一个bool值作为属性,判断按钮的点击
if(_flag) {
[sendersetTitle:@"结束直播"forState:0];
//初始化
LFLiveStreamInfo *stream = [[LFLiveStreamInfo alloc]init];
//将录制的视频传输到服务器上(该服务器为git上demo的服务器)
stream.url=@"rtmp://live.hkstv.hk.lxdns.com:1935/live/stream152";
[self.session startLive:stream];
}else{
[sender setTitle:@"开始直播" forState:0];
//停止直播
[self.session stopLive];
}
_flag= !_flag;
}
转跳到播放直播的页面
-(void)playAction:(UIButton*)sender{
[self.sessionstopLive];
[_liveButtonsetTitle:@"开始直播"forState:0];
_flag=YES;
UIStoryboard*storyboard = [UIStoryboardstoryboardWithName:@"Main"bundle:nil];
PlayViewController*playVC = [storyboardinstantiateViewControllerWithIdentifier:@"PlayViewController"];
[self.navigationControllerpushViewController:playVCanimated:YES];
}
实现代理,监听是否连接服务器成功
- (void)liveSession:(nullableLFLiveSession*)session liveStateDidChange:(LFLiveState)state {
NSLog(@"liveStateDidChange: %ld", state);
switch(state) {
caseLFLiveReady:
_stateLabel.text=@"未连接";
break;
caseLFLivePending:
_stateLabel.text=@"连接中";
break;
caseLFLiveStart:
_stateLabel.text=@"已连接";
break;
caseLFLiveError:
_stateLabel.text=@"连接错误";
break;
caseLFLiveStop:
_stateLabel.text=@"未连接";
break;
default:
break;
}
}
转换摄像头
-(void)cameraAction:(UIButton*)sender{
AVCaptureDevicePositiondevicePosition =self.session.captureDevicePosition;
self.session.captureDevicePosition= (devicePosition ==AVCaptureDevicePositionBack) ?AVCaptureDevicePositionFront:AVCaptureDevicePositionBack;
}
3、从服务器获取直播视频
导入我们拉进去的IJK包的头文件 #import<IJKMediaFramework/IJKMediaFramework.h>
设置属性
@property(nonatomic,strong)NSURL*url;
@property(nonatomic)id <IJKMediaPlayback>player;
@property(nonatomic,strong)UIView*showView;
//在viewWillAppear里面进行预播放
-(void)viewWillAppear:(BOOL)animated{
if(![self.playerisPlaying]) {
[self.playerprepareToPlay];
}
}
在viewDidLoad
//给url赋值服务器
_url= [NSURL URLWithString:@"rtmp://live.hkstv.hk.lxdns.com:1935/live/stream152"];
//初始化player
_player= [[IJKFFMoviePlayerController alloc]initWithContentURL:self.urlwithOptions:nil];
//将IJK里的view赋值给playerView
UIView *playerView = [self.player view];
UIView *displayView = [[UIView alloc]initWithFrame:self.view.bounds];
self.showView= displayView;
[self.viewaddSubview:_showView];
//将playerView的大小设置为全屏
playerView.frame=self.showView.bounds;
//调整比例
playerView.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
//将playerView作为showView的子视图
[self.showView insertSubview:playerView atIndex:1];
//按比例放置
[_player setScalingMode:IJKMPMovieScalingModeAspectFill];
基本上这样就完成了一个简单的直播demo了,有录制,有播放。github上传项目不知道为什么要打包之后才可以上传成功,所以下载demo之后要解压2次。demo