过去学习过如何扒代码,但是不明白为什么要去扒代码,后来工作之后也是慢慢的理解了;
还有就是学习别人写好的第三方框架,过去也不知道如何使用,慢慢的发现原来是看别人的源码;
不得不说,畅不在我身边之后,所有的事都要我自己扛,看英文文档,学习第三方使用,替换pod等等~
话说,看别人的demo,通读源码让人成长的真快~
也很感谢我离开了他的帮助,这让我一直再去独立成长,但也要非常感谢他曾经给我的帮助~
闲话少说,我们看看IJKPlayer的基本用法
首先还是要去看人家的demo,ijkplayer下载连接,然后运行脚本,看看demo中的内容,比较重要的是IJKFFMoviePlayerController
这个控制器,就是直接给他一个url,就可以播放了,真心非常优秀的播放框架!
白色和红色的是两个播放器
只是将小的播放器开启,大的关闭
大的和小圆都是播放器
看看源码
先要知道,白色的view叫做
MLLivePlayerCell
,红色的叫做MLCatEarView
首先要知道,MLLivePlayerCell
的播放器,是有声音的,并且我们做直播,最好要自己去控制他的播放时间,这要的效果比较好
#define EXPECTED_IJKPLAYER_VERSION (1 << 16) & 0xFF) | - (void)viewDidLoad { [super viewDidLoad]; //先去设置一下是否打印log,有利于我们去查看信息,但是正式情况下,最好关闭打印#ifdef DEBUG [IJKFFMoviePlayerController setLogReport:YES]; [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];#else [IJKFFMoviePlayerController setLogReport:NO]; [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_INFO];#endif [IJKFFMoviePlayerController checkIfFFmpegVersionMatch:YES]; // [IJKFFMoviePlayerController checkIfPlayerVersionMatch:YES major:1 minor:0 micro:0]; //这个一定要有,options 是对数据的处理,videotoolbox解码,设置音频视频等属性,都要有这个数据 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"]; self.player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:options]; self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; self.player.view.frame = self.view.bounds; self.player.scalingMode = IJKMPMovieScalingModeAspectFit; //如果是直播,最好不让他自动播放,如果YES,那么就会自动播放电影,不需要通过[self.player play];就可以播放了, //但是如果NO,我们需要注册通知,然后到响应比较合适的地方去检测通知,然后必须通过[self.player play];手动播放 self.player.shouldAutoplay = NO; self.view.autoresizesSubviews = YES; //player是个控制器,所以要吧他的view加载到self.view上 [self.view addSubview:self.player.view]; [self.view addSubview:self.mediaControl]; self.mediaControl.delegatePlayer = self.player; }
注册通知,准备播放,移除通知
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self installMovieNotificationObservers]; [self.player prepareToPlay]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.player shutdown]; [self removeMovieNotificationObservers]; }#pragma mark Install Movie Notifications/* Register observers for the various movie object notifications. */-(void)installMovieNotificationObservers { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadStateDidChange:) name:IJKMPMoviePlayerLoadStateDidChangeNotification object:_player]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackDidFinish:) name:IJKMPMoviePlayerPlaybackDidFinishNotification object:_player]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mediaIsPreparedToPlayDidChange:) name:IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification object:_player]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayBackStateDidChange:) name:IJKMPMoviePlayerPlaybackStateDidChangeNotification object:_player]; }#pragma mark Remove Movie Notification Handlers/* Remove the movie notification observers from the movie object. */-(void)removeMovieNotificationObservers { [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerLoadStateDidChangeNotification object:_player]; [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerPlaybackDidFinishNotification object:_player]; [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification object:_player]; [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerPlaybackStateDidChangeNotification object:_player]; }
这个代码是
喵播
的代码,这个是具体的项目中可能用到的东西,一般就注册2个通知就好了,可以监听到所需要的事情
- (void)stateDidChange { if ((self.moviePlayer.loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) { if (!self.moviePlayer.isPlaying) {//监听到了改变,判断是不是没有播放,然后播放,因为之前设置的时候,『自动播放=NO』,所以要在这里去给手动播放 [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.moviePlayer.view addSubview:_renderer.view]; } [self.parentVc hideGufLoding]; }); }else{ // 如果是网络状态不好, 断开后恢复, 也需要去掉加载 if (self.parentVc.gifView.isAnimating) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.parentVc hideGufLoding]; }); } } }else if (self.moviePlayer.loadState & IJKMPMovieLoadStateStalled){ // 网速不佳, 自动暂停状态 [self.parentVc showGifLoding:nil inView:self.moviePlayer.view]; } } - (void)didFinish { NSLog(@"加载状态...%ld %ld %s", self.moviePlayer.loadState, self.moviePlayer.playbackState, __func__); // 因为网速或者其他原因导致直播stop了, 也要显示GIF if (self.moviePlayer.loadState & IJKMPMovieLoadStateStalled && !self.parentVc.gifView) { [self.parentVc showGifLoding:nil inView:self.moviePlayer.view]; return; }// 方法:// 1、重新获取直播地址,服务端控制是否有地址返回。// 2、用户http请求该地址,若请求成功表示直播未结束,否则结束 __weak typeof(self)weakSelf = self; [[ALinNetworkTool shareTool] GET:self.live.flv parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"请求成功%@, 等待继续播放", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"请求失败, 加载失败界面, 关闭播放器%@", error); [weakSelf.moviePlayer shutdown]; [weakSelf.moviePlayer.view removeFromSuperview]; weakSelf.moviePlayer = nil; weakSelf.endView.hidden = NO; }]; }
self.moviePlayer.loadState & IJKMPMovieLoadStatePlaythroughOK
这个代码,是与,请参考这个文档,位运算和枚举,我就不赘述了~
切记,就是我们在结束的时候,
viewWillDisappear
中,设置[self.player shutdown]
,停止播放和self.player = nil
,移除播放器操作
看看MLCatEarView
中的设置
这个view中要去静音(业务需求),然后我们去设置代码
@interface MLCatEarView ()@property(nonatomic,strong)IJKFFMoviePlayerController *moviePlayer;@end@implementation MLCatEarView- (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor redColor]; self.layer.cornerRadius = 100*0.5; self.layer.masksToBounds = YES; } return self; } - (void)setLiveM:(MLLiveModel *)liveM{ _liveM = liveM; IJKFFOptions *option = [IJKFFOptions optionsByDefault]; //静音设置 [option setPlayerOptionValue:@"1" forKey:@"an"]; // 开启硬解码 [option setPlayerOptionValue:@"1" forKey:@"videotoolbox"]; IJKFFMoviePlayerController *moviePlayer = [[IJKFFMoviePlayerController alloc] initWithContentURLString:liveM.flv withOptions:option]; self.moviePlayer = moviePlayer; [self addSubview:self.moviePlayer.view]; self.moviePlayer.view.frame = self.bounds; self.moviePlayer.scalingMode = IJKMPMovieScalingModeAspectFill; //这里是自动播放,所以就没有[self.player play]这句话~ self.moviePlayer.shouldAutoplay = YES; [self.moviePlayer prepareToPlay]; } - (void)removeFromSuperview { if (_moviePlayer) { [_moviePlayer shutdown]; [_moviePlayer.view removeFromSuperview]; _moviePlayer = nil; } [super removeFromSuperview]; }
就这样写完了,有机会还是要看看源码,这样对自己的提升还是很大的,过去我学习一个框架,就是别人的博客,但是相比看源码,理解的还是有些偏差~
作者:王鑫20111
链接:https://www.jianshu.com/p/8b299f3a0629
热门评论
你的图片已经失效了 看不到内容