美文网首页iOS
IJKMediaFramework、LFLiveKit实现视频直

IJKMediaFramework、LFLiveKit实现视频直

作者: weiweilong | 来源:发表于2017-04-06 11:30 被阅读502次

    视频直播

    <h5>拉流:</h5>

    从服务器获取视频直播流地址,播放直播 使用IJKMediaFramework.framework
    使用:

        IJKFFOptions *options = [IJKFFOptions optionsByDefault];
        [options setPlayerOptionIntValue:1  forKey:@"videotoolbox"];
        // 帧速率(fps) (可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
        [options setPlayerOptionIntValue:29.97 forKey:@"r"];
        // -vol——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推
        [options setPlayerOptionIntValue:512 forKey:@"vol"];
        IJKFFMoviePlayerController *moviePlayer = [[IJKFFMoviePlayerController alloc] initWithContentURLString:flv withOptions:options];
        moviePlayer.view.frame = self.contentView.bounds;
        // 填充fill
        moviePlayer.scalingMode = IJKMPMovieScalingModeAspectFill;
        // 设置自动播放(必须设置为NO, 防止自动播放, 才能更好的控制直播的状态)
        moviePlayer.shouldAutoplay = NO;
        // 默认不显示
        moviePlayer.shouldShowHudView = NO;
        
        [self.contentView insertSubview:moviePlayer.view atIndex:0];
        
        [moviePlayer prepareToPlay];
        
        self.moviePlayer = moviePlayer;
    
    

    <h5>推流:</h5>

    开始直播,视频采集和视频流处理与传输
    直播采用L
    LFLiveKit 支持的流类型
    rtmp格式 、 tcp 传输flv格式

    <h5>使用</h5>
    开播逻辑

    - (void)startLive {
        MPLiveModel *liveModel = [ZQGlobalObject sharedZQGlobalObject].liveModel;
        // 拼接推流地址 “url/流名”
        NSString *url = [NSString stringWithFormat:@"%@/%@", liveModel.rtmpUrl, liveModel.videoId];
        // 创建流对象
        LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
        stream.url = url;
        // 推流对象开始推流
        [_session startLive:stream];
    }
    

    进出后台处理

    #pragma mark 应用程序通知监听
    - (void)applicationNotification:(NSNotification *)note {
        if (_session) {
            // 进入后台
            if (note.name == UIApplicationDidEnterBackgroundNotification) { // 进入后台
                NSLog(@"进入后台");
                [_controlView pauseLive];
            // 从后台回到直播间
            } else if (note.name == UIApplicationWillEnterForegroundNotification) {
                if (!_session.running) {
                    _session.running = YES;
                }
                [self startLive];
            }
        }
    }
    

    退出直播间,释放对象

    - (void)dealloc {
        if (_session) {
            _session.delegate = nil;
            _session = nil;
        }
        NSLog(@"退出直播间");
    }
    

    创建推流对象并设置播放参数

    - (LFLiveSession *)session {
        if(!_session){
           
            _session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Medium2 orientation:UIInterfaceOrientationPortrait] liveType:LFLiveRTMP];
            _session.delegate = self;
            _session.running = YES;
            _session.preView = _preview;
        }
        return _session;
    }
    

    创建推流要展示推流效果的视图对象

    - (MPLiveControlView *)controlView {
        if (_controlView == nil) {
            _controlView = [[MPLiveControlView alloc] initWithFrame:self.view.frame];
            _controlView.delegate = self;
            _controlView.session = self.session;
        }
        return _controlView;
    }
    

    推流状态的回调

    - (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange:(LFLiveState)state{
        NSLog(@"liveStateDidChange: %ld", state);
        WS(weakSelf);
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (state) {
                case LFLiveReady:
                    [weakSelf.controlView setLiveState:MPLiveStateLoading];
                    break;
                case LFLivePending:
                    [weakSelf.controlView setLiveState:MPLiveStateLoading];
                    break;
                case LFLiveStart:
                    [weakSelf.controlView setLiveState:MPLiveStatePlay];
                    break;
                case LFLiveError:
        //            _stateLabel.text = @"连接错误";
                    break;
                case LFLiveStop:
                    [weakSelf.controlView setLiveState:MPLiveStateStop];
                    break;
                default:
                    break;
            }
        });
    }
    - (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo{
        NSLog(@"debugInfo: %lf", debugInfo.dataFlow);
    }
    - (void)liveSession:(nullable LFLiveSession*)session errorCode:(LFLiveSocketErrorCode)errorCode{
        NSLog(@"errorCode: %ld", errorCode);
    }
    

    弹幕可以使用BarrageRenderer

    简单使用:

    _renderer = [[BarrageRenderer alloc] init];
    // 设置弹幕的显示区域. 基于父控件的.
    _renderer.canvasMargin = UIEdgeInsetsMake(ALinScreenHeight * 0.3, 10, 10, 10);
    [self.contentView addSubview:_renderer.view];
    

    弹幕配置

    #pragma mark - 弹幕描述符生产方法
    /// 生成精灵描述 - 过场文字弹幕
    - (BarrageDescriptor *)walkTextSpriteDescriptorWithDirection:(NSInteger)direction
    {
        BarrageDescriptor * descriptor = [[BarrageDescriptor alloc]init];
        descriptor.spriteName = NSStringFromClass([BarrageWalkTextSprite class]);
        descriptor.params[@"text"] = self.danMuText[arc4random_uniform((uint32_t)self.danMuText.count)];
        descriptor.params[@"textColor"] = Color(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256));
        descriptor.params[@"speed"] = @(100 * (double)random()/RAND_MAX+50);
        descriptor.params[@"direction"] = @(direction);
        descriptor.params[@"clickAction"] = ^{
            UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示" message:@"弹幕被点击" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
            [alertView show];
        };
        return descriptor;
    }
     
    [_renderer start];
    

    相关文章

      网友评论

        本文标题:IJKMediaFramework、LFLiveKit实现视频直

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