一、nginx + rtmp +ffmpeg服务器安装教程
地址://www.greatytc.com/p/b1207e41edaf
二、LFLiveKit库(推流)
使用Cocoapod导入LFLiveKit库
三、IJKMediaPlayer库集成教程(拉流)
地址://www.greatytc.com/p/82f435ae21cf
四:配置手机网络
1、配置好nginx服务器的Mac和ipone连接同一个wifi
2、查看Mac当前网络IP
3、进入手机当前网络的配置代理,将服务器ip设置为Mac的ip,端口为8080
五:代码实现
推流
#import <LFLiveKit.h>
#import <AVFoundation/AVFoundation.h>
@interface RecordingViewController ()<LFLiveSessionDelegate>
@property (nonatomic,strong) LFLiveSession *session;
@end
@implementation RecordingViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self beatutyfaceBtn];
//录制端
[self requestAccessForVidoe];
[self requestAudio];
[self startLive];
}
- (void)beatutyfaceBtn{
UIButton *actionBtn = [UIButton buttonWithType:UIButtonTypeSystem];
actionBtn.backgroundColor = [UIColor redColor];
[actionBtn setTitle:@"开始直播" forState:UIControlStateNormal];
[actionBtn addTarget:self action:@selector(openBeatyface:) forControlEvents:UIControlEventTouchUpInside];
actionBtn.frame = CGRectMake(self.view.center.x - 50, 400, 100, 50);
[self.view addSubview:actionBtn];
}
- (LFLiveSession*)session {
if (!_session) {
_session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
_session.preView = self.view;
_session.showDebugInfo = YES;
_session.delegate = self;
}
return _session;
}
//获取系统的摄像头权限,获取视屏资源:
- (void)requestAccessForVidoe{
__weak typeof (self) weakSelf = self;
//判断授权状态
AVAuthorizationStatus statues = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (statues) {
case AVAuthorizationStatusNotDetermined:{
//发起授权请求
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
//进行会话
[weakSelf.session setRunning:YES];
});
}
}];
break;
}
case AVAuthorizationStatusAuthorized:{
//已授权继续
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.session setRunning:YES];
});
break;
}
default:
break;
}
}
//获取音频权限与资源:
- (void)requestAudio
{
__weak typeof (self) weakSelf = self;
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
switch (status) {
case AVAuthorizationStatusNotDetermined:{
//发起授权请求
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
//进行会话
[weakSelf.session setRunning:YES];
});
}
}];
break;
}
case AVAuthorizationStatusAuthorized:{
//授权继续
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf.session setRunning:YES];
});
}
default:
break;
}
}
//LFLivekit监听delegate方法:
- (void)liveSession:(LFLiveSession *)session errorCode:(LFLiveSocketErrorCode)errorCode
{
//弹出警告
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Warning" message:@"链接错误,请检查IP地址" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"sure" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self.navigationController popViewControllerAnimated:YES];
}];
[alert addAction:sure];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)startLive {
LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
streamInfo.url = @"rtmp://192.168.1.121:1935/rtmplive/room";
[self.session startLive:streamInfo];
}
- (void)openBeatyface:(UIButton *)btn{
_session.beautyFace = YES;
}
- (void)stopLive {
[self.session stopLive];
}
//MARK: - CallBack:
- (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange: (LFLiveState)state{
}
- (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo{
}
- (void)viewDidDisappear:(BOOL)animated{
[self stopLive];
}
@end
拉流
#import <IJKMediaFramework/IJKFFMoviePlayerController.h>
@interface PlayLiveViewController ()
@property(nonatomic,strong)IJKFFMoviePlayerController * player;
@end
@implementation PlayLiveViewController
- (void)viewDidLoad {
[super viewDidLoad];
IJKFFOptions *options = [IJKFFOptions optionsByDefault]; //使用默认配置
NSURL * url = [NSURL URLWithString:@"rtmp://192.168.1.121:1935/rtmplive/room"];
self.player = [[IJKFFMoviePlayerController alloc] initWithContentURL:url withOptions:options];
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.player.view.frame = self.view.bounds;
self.player.scalingMode = IJKMPMovieScalingModeAspectFit;
self.player.shouldAutoplay = YES;
self.view.autoresizesSubviews = YES;
[self.view addSubview:self.player.view];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.player prepareToPlay];
}
-(void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.player shutdown];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
rtmp://192.168.1.121:1935/rtmplive/room
192.168.1.121:nginx 所在Mac的当前网络ip
注意事项:
plist添加
Privacy - Camera Usage Description 相机
Privacy - Microphone Usage Description 录音
Privacy - Photo Library Usage Description 相册
简单写了一个实现简易直播效果的demo
地址:https://gitee.com/xu_sheng_jie/live-demo.git