美文网首页iOS专题资源__工具专题iOS
IOS直播理解章节四-直播拉流IJKMediaFramework

IOS直播理解章节四-直播拉流IJKMediaFramework

作者: 887d1fc86fe6 | 来源:发表于2016-09-12 17:49 被阅读281次

    原文地址:http://www.cnblogs.com/fusheng-it/p/5760841.html

    IJKMediaFramework 文件生成: http://www.jianshu.com/p/b7a646a6c80e

    推流完成后,需要拉流才能进行完整的直播。拉流我们采用的也是一个开源的第三方库IJKMediaFramework。

    这个库本质是一个播放器,能播放flv格式的播放器。用起来和ios自带的AVPlayer很相似。

    实现功能:1.拉流播放。2.监听。

    一.创建占位图和卡顿占位动效,代码如下:

    //直播前的占位图片

    - (UIImageView *)placeHolderView

    {if(!_placeHolderView) {

    _placeHolderView=[[UIImageView alloc] init];

    _placeHolderView.frame=self.view.bounds;

    _placeHolderView.image= [UIImage imageNamed:@"profile_user_414x414"];

    //强制布局

    [_placeHolderView layoutIfNeeded];

    }

    return_placeHolderView;

    }

    //卡顿占位动效

    - (void)showActivityView{if(!_activity) {

    _activity=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    _activity.frame= CGRectMake((SCREAM_WEIGHT-100)*0.5, (SCREAM_HIGHT-100)*0.5,100,100);

    }

    [self.activity startAnimating];

    [self.view addSubview:self.activity];

    }

    //关闭卡顿占位动效

    - (void)stopActivityView{if([_activity isAnimating]) {

    [_activity startAnimating];

    }

    [_activity removeFromSuperview];

    _activity=nil;

    }

    二.拉流播放(创建播放器播放),代码如下:

    - (void)viewDidLoad {

    [super viewDidLoad];

    [self.view addSubview:self.placeHolderView];

    [self showActivityView];

    IJKFFOptions*options =[IJKFFOptions optionsByDefault];

    [options setPlayerOptionIntValue:1forKey:@"videotoolbox"];

    //帧速率(fps) (可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)

    [options setPlayerOptionIntValue:29.97forKey:@"r"];

    //-vol——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推

    [options setPlayerOptionIntValue:512forKey:@"vol"];

    IJKFFMoviePlayerController*moviePlayer =[[IJKFFMoviePlayerController alloc] initWithContentURLString:PLAY_URL withOptions:options];

    moviePlayer.view.frame=self.view.bounds;

    moviePlayer.scalingMode=IJKMPMovieScalingModeAspectFill;

    //设置自动播放(必须设置为NO, 防止自动播放, 才能更好的控制直播的状态)

    moviePlayer.shouldAutoplay =NO;

    //默认不显示

    moviePlayer.shouldShowHudView =NO;

    [self.view insertSubview:moviePlayer.view atIndex:0];

    [moviePlayer prepareToPlay];

    self.moviePlayer=moviePlayer;

    //设置监听

    [self addObserver];

    [self.view addSubview:self.outBtn];

    }

    三.设置监听(主要是监听缓存情况),代码如下:

    - (void)addObserver

    {//监听加载状态改变通知

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadStateDidChange:) name:IJKMPMoviePlayerLoadStateDidChangeNotificationobject:self.moviePlayer];

    }

    - (void)loadStateDidChange:(NSNotification *) notification

    {//状态为缓冲几乎完成,可以连续播放

    if((self.moviePlayer.loadState & IJKMPMovieLoadStatePlaythroughOK) !=0) {

    if(!self.moviePlayer.isPlaying) {

    //开始播放

    [self.moviePlayer play];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{if(_placeHolderView) {

    [_placeHolderView removeFromSuperview];

    _placeHolderView=nil;

    }

    [self stopActivityView];

    });

    }else{

    //如果是网络状态不好, 断开后恢复, 也需要去掉加载

    if ([_activity isAnimating]) {

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    [self stopActivityView];

    });

    }

    }

    }

    //缓冲中

    else if (self.moviePlayer.loadState &IJKMPMovieLoadStateStalled) {

    [self showActivityView];

    /*这里主播可能已经结束直播了。我们需要请求服务器查看主播是否已经结束直播。

    方法:

    1、从服务器获取主播是否已经关闭直播。

    优点:能够正确的获取主播端是否正在直播。

    缺点:主播端异常crash的情况下是没有办法通知服务器该直播关闭的。

    2、用户http请求该地址,若请求成功表示直播未结束,否则结束

    优点:能够真实的获取主播端是否有推流数据

    缺点:如果主播端丢包率太低,但是能够恢复的情况下,数据请求同样是失败的。*/

    __weaktypeof(self)weakSelf =self;

    [[ALinNetworkTool shareTool] GET:PLAY_URL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id_Nullable responseObject) {

    NSLog(@"请求成功%@, 等待继续播放", responseObject);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError *_Nonnull error) {

    NSLog(@"请求失败, 加载失败界面, 关闭播放器%@", error);

    [weakSelf performSelector:@selector(outBtnTouched)];

    }];

    }

    }

    四.记得关闭前释放

    - (void)dealloc{if(_moviePlayer) {

    [_moviePlayer shutdown];

    [_moviePlayer.view removeFromSuperview];

    _moviePlayer=nil;

    }

    [[NSNotificationCenter defaultCenter]removeObserver:self];

    }

    总结:项目中还有许多缺陷等待一一完善。

    相关文章

      网友评论

        本文标题:IOS直播理解章节四-直播拉流IJKMediaFramework

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