[bilibili/ijkplayer]iOS做直播,应用进入后台再次进入前台,视频会卡住

2024-08-20 918 views
4

iOS做直播,应用进入后台再次进入前台,视频会卡住,如果重新再创建一个player确实可以重新播放,但是观察层级图可以发现有两个Player界面叠加在了一起,这样如果一直重新创建就会一直叠加下去,程序肯定出问题。请问有没有方法能够把原来的那个Player销毁掉。

回答

6

@xinzhengzhang shutdown用了确实能让视频停止,但是要移除整个界面这种方式并不好,有移除播放器的方法吗,我想重新创建一个播放器,把旧的播放器删除。

2

你好,buddy,你的rtsp可以播放么?我这边播放加载慢,而且会提示加载失败,停止播放,方便的留个企鹅号吧,求教,谢谢

2

@jiangbin1993 问题有解决吗?我播RTSP也遇到从后台进前台视频卡死的问题了。

0

@BelindaFly 解决了 从后台进入前台把之前的player移除 再创建一个新的player重新播放视频就可以了

5

@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;

    ijkmp_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");
    ifdef DEBUG
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
    else
    [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_SILENT];
    endif
    // 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]; }
2

@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]; }

先写这么多 有问题再说。

2

@jiangbin1993 self.isPlayingVideo和self.isVideoCovered是代表啥意思啊,我不判断有影响么。。。麻烦你了😁

7

@BelindaFly 没有影响的 因为我的项目是有另外的界面覆盖住播放控制器的情况发生,所以我做了判断

2

@jiangbin1993 哈哈秒回啊,我用你的方法调调试试,感谢大神的支持😄

1

我播放5-6次就出现一次加载慢+延迟高的情况,感觉创建了player得了重病一样! 排除不是网速问题,因为vlc2.2.6播放同一个源是正常的, 目前想到解决思路也就是换player