Ijkplayer: 直播网络环境从WiFi切换到4g,中断后如何重连?

Created on 6 Apr 2017  ·  3Comments  ·  Source: bilibili/ijkplayer

我在使用IJKFFMoviePlayerController播放器的时候遇到一个问题,播放器拉流播放直播的时候,从wifi转到4g网络,过不了多久,就会发一个 IJKMPMoviePlayerPlaybackDidFinishNotification 的通知提示网络中断了,中断原因是IJKMPMovieFinishReasonPlaybackError,然后我尝试播放器停止再重新播放,会直接崩溃,我想问一下有人知道正确的重新播放的操作吗?我的是直接 [self.player stop];
[self.player prepareToPlay];
[self.player play];

Most helpful comment

  1. 捕获 IJKMPMovieLoadStateStalled通知;例如,
- (void)didLoadingStateChange:(NSNotification*)notification
{
    if (self.loadingStateHandler) {
        IJKMPMovieLoadState loadState = self.mediaPlayer.loadState;

        if ((loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStatePlayThrough);
        }
        else if ((loadState & IJKMPMovieLoadStateStalled) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStateStalled);

            [self startRecoveryTimer];
        }
        else if ((loadState & IJKMPMovieLoadStatePlayable) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStatePlayable);
        }
        else {
            self.loadingStateHandler(GCLivePlayerLoadingStateUnknown);
        }
    }
}

  1. 启动重试并恢复的定时器;例如,每2秒重试一次。
- (void)startRecoveryTimer
{
    self.recoveryPeriodic = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(recoveryTimerFired) userInfo:nil repeats:YES];
}

  1. 在定时器的回调中重新初始化与 cdn 的连接;
- (void)recoveryTimerFired
{
    NSLog(@"Recovery timer fired");

    [self.mediaPlayer stop];

    [self removeMediaPlayerObservers];

    [self.mediaPlayer.view removeFromSuperview];
//    [self.mediaPlayer shutdown];
    [self setMediaPlayer:nil];

    NSLog(@"Recovery timer fired: stop");

    IJKFFOptions *options = [IJKFFOptions optionsByDefault];

    self.mediaPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:self.assetUrl] withOptions:options];
    [self.mediaPlayer.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self.mediaPlayer.view setFrame:self.playerView.bounds];
    [self.mediaPlayer setScalingMode:IJKMPMovieScalingModeAspectFill];
    [self.mediaPlayer setShouldAutoplay:self.shouldAutoPlay];
    [self.mediaPlayer.view setBackgroundColor:[UIColor clearColor]];

    [self.playerView addSubview:self.mediaPlayer.view];

    [self.mediaPlayer prepareToPlay];

    [self addMediaPlayerObservers];

    NSLog(@"Recovery timer fired: play");
}

All 3 comments

有经验的可以说一下吗?谢谢了!

  1. 捕获 IJKMPMovieLoadStateStalled通知;例如,
- (void)didLoadingStateChange:(NSNotification*)notification
{
    if (self.loadingStateHandler) {
        IJKMPMovieLoadState loadState = self.mediaPlayer.loadState;

        if ((loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStatePlayThrough);
        }
        else if ((loadState & IJKMPMovieLoadStateStalled) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStateStalled);

            [self startRecoveryTimer];
        }
        else if ((loadState & IJKMPMovieLoadStatePlayable) != 0) {
            self.loadingStateHandler(GCLivePlayerLoadingStatePlayable);
        }
        else {
            self.loadingStateHandler(GCLivePlayerLoadingStateUnknown);
        }
    }
}

  1. 启动重试并恢复的定时器;例如,每2秒重试一次。
- (void)startRecoveryTimer
{
    self.recoveryPeriodic = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(recoveryTimerFired) userInfo:nil repeats:YES];
}

  1. 在定时器的回调中重新初始化与 cdn 的连接;
- (void)recoveryTimerFired
{
    NSLog(@"Recovery timer fired");

    [self.mediaPlayer stop];

    [self removeMediaPlayerObservers];

    [self.mediaPlayer.view removeFromSuperview];
//    [self.mediaPlayer shutdown];
    [self setMediaPlayer:nil];

    NSLog(@"Recovery timer fired: stop");

    IJKFFOptions *options = [IJKFFOptions optionsByDefault];

    self.mediaPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:self.assetUrl] withOptions:options];
    [self.mediaPlayer.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self.mediaPlayer.view setFrame:self.playerView.bounds];
    [self.mediaPlayer setScalingMode:IJKMPMovieScalingModeAspectFill];
    [self.mediaPlayer setShouldAutoplay:self.shouldAutoPlay];
    [self.mediaPlayer.view setBackgroundColor:[UIColor clearColor]];

    [self.playerView addSubview:self.mediaPlayer.view];

    [self.mediaPlayer prepareToPlay];

    [self addMediaPlayerObservers];

    NSLog(@"Recovery timer fired: play");
}

如果中断了,会有错误的通知消息,如果需要继续播放,就需要根据当前的网络状态来判断需不需要继续播放,我的做法就是收到错误信息之后就会把视频播放器释放掉,需要创建的时候再创建视频播放器。

Was this page helpful?
0 / 5 - 0 ratings