美文网首页
iOS 开发直播app(nginx+LFLiveKit+IJKM

iOS 开发直播app(nginx+LFLiveKit+IJKM

作者: 真香_7e73 | 来源:发表于2022-09-13 17:09 被阅读0次

    一、nginx + rtmp +ffmpeg服务器安装教程
    地址:https://www.jianshu.com/p/b1207e41edaf

    二、LFLiveKit库(推流)
    使用Cocoapod导入LFLiveKit库

    三、IJKMediaPlayer库集成教程(拉流)
    地址:https://www.jianshu.com/p/82f435ae21cf

    四:配置手机网络
    1、配置好nginx服务器的Mac和ipone连接同一个wifi
    2、查看Mac当前网络IP


    image.png

    3、进入手机当前网络的配置代理,将服务器ip设置为Mac的ip,端口为8080


    image.png

    五:代码实现
    推流

    
    #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

    相关文章

      网友评论

          本文标题:iOS 开发直播app(nginx+LFLiveKit+IJKM

          本文链接:https://www.haomeiwen.com/subject/rvxlortx.html