• iOS简单直播实现(二:推流)


      推流用的是一个第三方的IFLiveKit框架。这个框架基于rtmp协议的,c语言和oc语言分开的非常清楚,对oc语言非常友好,使用起来相对简单。

      IFLiveKit内部集成了GPUIImage。内部实现了图片渲染等美艳效果。减少了开发时候美艳效果的调试。

      需求:创建一个简单的推流页面。包含功能有:1.推流状态监听。2.切换摄像头。3.切换美艳效果。4.开关推流。

    一.推流之前需要检查摄像头和麦克风等权限是否开启,并启动摄像头,核心代码如下:

    //判断是否有摄像头
        if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
            [self showInfo:@"您的设备没有摄像头或者相关的驱动, 不能进行直播"];
            return;
        }
        //判断是否有摄像头权限
        AVAuthorizationStatus  authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if (authorizationStatus == AVAuthorizationStatusRestricted|| authorizationStatus == AVAuthorizationStatusDenied) {
            [self showInfo:@"app需要访问您的摄像头。
    请启用摄像头-设置/隐私/摄像头"];
            return ;
        }
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
            [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
                if (granted) {
                    return YES;
                }
                else {
                    [self showInfo:@"app需要访问您的麦克风。
    请启用麦克风-设置/隐私/麦克风"];
                    return NO;
                }
            }];
        }

    二.创建一个按钮.点击开始推流代码如下:

    - (LFLiveSession*)session{
        if(!_session){
            /***   默认分辨率368 * 640  音频:44.1 iphone6以上48  双声道  方向竖屏 ***/
            _session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Medium2]];
            
            /**    自己定制高质量音频128K 分辨率设置为720*1280 方向竖屏 */
            /*
             LFLiveAudioConfiguration *audioConfiguration = [LFLiveAudioConfiguration new];
             audioConfiguration.numberOfChannels = 2;
             audioConfiguration.audioBitrate = LFLiveAudioBitRate_128Kbps;
             audioConfiguration.audioSampleRate = LFLiveAudioSampleRate_44100Hz;
             
             LFLiveVideoConfiguration *videoConfiguration = [LFLiveVideoConfiguration new];
             videoConfiguration.videoSize = CGSizeMake(720, 1280);
             videoConfiguration.videoBitRate = 800*1024;
             videoConfiguration.videoMaxBitRate = 1000*1024;
             videoConfiguration.videoMinBitRate = 500*1024;
             videoConfiguration.videoFrameRate = 15;
             videoConfiguration.videoMaxKeyframeInterval = 30;
             videoConfiguration.orientation = UIInterfaceOrientationPortrait;
             videoConfiguration.sessionPreset = LFCaptureSessionPreset720x1280;
             
             _session = [[LFLiveSession alloc] initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration liveType:LFLiveRTMP];
             */
            
            // 设置代理
            _session.delegate = self;
            _session.running = YES;
            _session.preView = self.livingPreView;
        }
        return _session;
    }
    
    - (IBAction)startTouched:(id)sender {
        LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
        // 本地推流地址
        stream.url = @"rtmp://192.168.199.131:1935/rtmplive/room";
        self.rtmpUrl = stream.url;
        [self.session startLive:stream];
    }

    3.创建一个按钮点击关闭推流,代码如下

    - (IBAction)endTouched:(id)sender {
        // 结束直播
        [self.session stopLive];
        self.stateLable.text = [NSString stringWithFormat:@"状态: 直播被关闭
    RTMP: %@", self.rtmpUrl];
    }

    4.创建一个按钮点击切换前后摄像头,代码如下

    - (IBAction)camaBtnTouched:(id)sender {
        AVCaptureDevicePosition devicePositon = self.session.captureDevicePosition;
        self.session.captureDevicePosition = (devicePositon == AVCaptureDevicePositionBack) ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack;
        NSLog(@"切换前置/后置摄像头");
    }

    5.创建一个按钮设置美艳功能,代码如下

    - (IBAction)beautiyBtnTouched:(id)sender {
        ((UIButton*)sender).selected = !((UIButton*)sender).selected;
        // 默认是开启了美颜功能的
        self.session.beautyFace = !self.session.beautyFace;
    }

    6.推流状态监听,接受代理,代码如下:

    #pragma mark -- LFStreamingSessionDelegate
    /** live status changed will callback */
    - (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange:(LFLiveState)state{
        NSString *tempStatus;
        switch (state) {
            case LFLiveReady:
                tempStatus = @"准备中";
                break;
            case LFLivePending:
                tempStatus = @"连接中";
                break;
            case LFLiveStart:
                tempStatus = @"已连接";
                break;
            case LFLiveStop:
                tempStatus = @"已断开";
                break;
            case LFLiveError:
                tempStatus = @"连接出错";
                break;
            default:
                break;
        }
        self.stateLable.text = [NSString stringWithFormat:@"状态: %@
    RTMP: %@", tempStatus, self.rtmpUrl];
    }
    
    /** live debug info callback */
    - (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo{
        
    }
    
    /** callback socket errorcode */
    - (void)liveSession:(nullable LFLiveSession*)session errorCode:(LFLiveSocketErrorCode)errorCode{
        
    }

    6.自己也需要看到自己的推流画面,并观察美艳效果,代码如下:

    - (UIView *)livingPreView
    {
        if (!_livingPreView) {
            UIView *livingPreView = [[UIView alloc] initWithFrame:self.view.bounds];
            livingPreView.backgroundColor = [UIColor clearColor];
            livingPreView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            [self.view insertSubview:livingPreView atIndex:0];
            _livingPreView = livingPreView;
        }
        return _livingPreView;
    }

    至此,完成了推流工作。

    -----------------------------分割线-------------------------------------

      新手上路,共同进步群号:240970537

  • 相关阅读:
    nrm安装与配置
    vue-cli2升级到webpack4
    npm和yarn的区别
    Vite和Vue CLI的优劣
    基于vue+element+select实现的自定义控件selectTree
    Extjs 隐藏tabpanel的header / title
    await/async 总结
    泛型
    jpg图片打包生成pdf文件的几种方式
    varchar(100)和varchar(10)的区别
  • 原文地址:https://www.cnblogs.com/fusheng-it/p/5760271.html
Copyright © 2020-2023  润新知