iOS做直播,应用进入后台再次进入前台,视频会卡住,如果重新再创建一个player确实可以重新播放,但是观察层级图可以发现有两个Player界面叠加在了一起,这样如果一直重新创建就会一直叠加下去,程序肯定出问题。请问有没有方法能够把原来的那个Player销毁掉。
[bilibili/ijkplayer]iOS做直播,应用进入后台再次进入前台,视频会卡住
回答
@xinzhengzhang shutdown用了确实能让视频停止,但是要移除整个界面这种方式并不好,有移除播放器的方法吗,我想重新创建一个播放器,把旧的播放器删除。
你好,buddy,你的rtsp可以播放么?我这边播放加载慢,而且会提示加载失败,停止播放,方便的留个企鹅号吧,求教,谢谢
@jiangbin1993 问题有解决吗?我播RTSP也遇到从后台进前台视频卡死的问题了。
@BelindaFly 解决了 从后台进入前台把之前的player移除 再创建一个新的player重新播放视频就可以了
@jiangbin1993 您具体代码如何实现的呢?我是小白,求抱大腿。。。 按照我自己的理解做的,但是偶尔还是会出现从后台进入前台播放卡住的问题,特别是锁屏之后再解锁的情况。还望大神指点一二。。。
我的做法如下: step1:在IJKFFMoviePlayerController中加了两个方法
-
(void)willEnterBackground { [self shutdown]; }
-
(void)willEnterForeground { if (!_mediaPlayer) { _mediaPlayer = ijkmp_ios_create(media_player_msg_loop); _msgPool = [[IJKFFMoviePlayerMessagePool alloc] init]; IJKWeakHolder *weakHolder = [IJKWeakHolder new]; weakHolder.object = self;
ifdef DEBUGijkmp_set_weak_thiz(_mediaPlayer, (__bridge_retained void *) self); ijkmp_set_inject_opaque(_mediaPlayer, (__bridge_retained void *) weakHolder); ijkmp_set_option_int(_mediaPlayer, IJKMP_OPT_CATEGORY_PLAYER, "start-on-prepared", _shouldAutoplay ? 1 : 0); ijkmp_ios_set_glview(_mediaPlayer, _glView); ijkmp_set_option(_mediaPlayer, IJKMP_OPT_CATEGORY_PLAYER, "overlay-format", "fcc-_es2");
else[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
endif[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_SILENT];
// init audio sink [[IJKAudioKit sharedInstance] setupAudioSession]; IJKFFOptions *options = [IJKFFOptions optionsByDefault]; [options applyTo:_mediaPlayer]; [self registerApplicationObservers]; [self prepareToPlay];
} } step2:在IJKMoviePlayerViewController文件中设置全局player IJKAppDelegate appDelegate = (IJKAppDelegate )[[UIApplication sharedApplication] delegate]; appDelegate.playerControl = self.player;
step3: IJKAppDelegate中
- (void)applicationDidEnterBackground:(UIApplication *)application { [self.playerControl willEnterBackground]; }
- (void)applicationWillEnterForeground:(UIApplication *)application { [self.playerControl willEnterForeground]; }
@BelindaFly 因为我考虑到切换网络的情况,而且当时写的时候没有用到退到后台和进入前台的通知,我的代码是写在appdelegate退出后台进入前台的方法里, 所以和你写的不一样,但是原理是一样的。
先说一下我的思路: 退到后台时,在appdelegate.m 的applicationDidEnterBackground:(UIApplication )application方法里找到IJKVideoViewController控制器(就是ijkmoviecontroller,我是通过为控制器的view设置tag值,然后在appdelegate里通过tag值找到的,不建议把这个控制器作为appdelegate的属性,这样会导致控制器无法被释放的),然后关闭播放器,移除播放器 进入前台时,在appdelegate.m 的applicationWillEnterForeground:(UIApplication )application方法里找到IJKVideoViewController控制器,重新创建播放器,建立连接,开始播放。 实际实现时因为项目比较复杂,所以添加了很多操作,但是实现原理就是上面所述。 代码: 1.退到后台
-
(void)applicationDidEnterBackground:(UIApplication *)application {
if (self.isPlayingVideo) { if (self.isVideoCovered) { self.isReloadPlayer = YES; }else{ UIView view = [self.window viewWithTag:88888]; IJKVideoViewController vc = (IJKVideoViewController *)view.nextResponder; [vc.player shutdown]; [vc.player.view removeFromSuperview]; self.isReloadPlayer = NO; } } }
2.回到前台
-
(void)applicationWillEnterForeground:(UIApplication *)application {
if (self.isPlayingVideo && !self.isVideoCovered) { UIView view = [self.window viewWithTag:88888]; IJKVideoViewController vc = (IJKVideoViewController *)view.nextResponder; [vc reloadPlayer];// 重新加载播放器 } }
3.IJKMoviePlayerViewController中代码reloadPlayer方法如下
pragma mark 重新加载播放器-
(void)reloadPlayer{
[IJKFFMoviePlayerController checkIfFFmpegVersionMatch:YES]; IJKFFOptions options = [IJKFFOptions optionsByDefault]; [options setFormatOptionValue:@"ijktcphook" forKey:@"http-tcp-hook"]; 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; self.player.shouldAutoplay = YES; self.view.autoresizesSubviews = YES; [self.view addSubview:self.player.view]; [self.player prepareToPlay]; // UIViewController vc2 = self.childViewControllers[0]; // [self.view bringSubviewToFront:vc2.view]; [self.view insertSubview:self.player.view atIndex:1]; }
先写这么多 有问题再说。
@jiangbin1993 self.isPlayingVideo和self.isVideoCovered是代表啥意思啊,我不判断有影响么。。。麻烦你了😁
@BelindaFly 没有影响的 因为我的项目是有另外的界面覆盖住播放控制器的情况发生,所以我做了判断
@jiangbin1993 哈哈秒回啊,我用你的方法调调试试,感谢大神的支持😄
我播放5-6次就出现一次加载慢+延迟高的情况,感觉创建了player得了重病一样! 排除不是网速问题,因为vlc2.2.6播放同一个源是正常的, 目前想到解决思路也就是换player