6.6.5拉流

拉流我们使用IJKplayer框架,本节具体介绍IJKplayer框架具体拉流过程。

实现步骤

1.引入头文件

#import <IJKMediaFramework/IJKMediaFramework.h>
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>

2.创建变量

@property (atomic, strong) NSURL *url;
@property (atomic, retain) id <IJKMediaPlayback> player;

3.初始化player

    _player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:nil];

    UIView *playerView = [self.player view];
    UIView *displayView = [[UIView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, 500)];
    self.PlayerView = displayView;
    self.PlayerView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.PlayerView];

    playerView.frame = self.PlayerView.bounds;
    playerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self.PlayerView insertSubview:playerView atIndex:1];
    //缩放模式为FILL
    [_player setScalingMode:IJKMPMovieScalingModeAspectFill];

4.设置IJKFFOptions

  • 设备参数设置
    IJKFFOptions *options = [IJKFFOptions optionsByDefault]; //使用默认配置

    //开启硬解码
    [options setPlayerOptionIntValue:0 forKey:@"videotoolbox"];

    // 设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推)
    [options setPlayerOptionIntValue:512 forKey:@"vol"];

    // 最大fps
    [options setPlayerOptionIntValue:30 forKey:@"max-fps"];

    // 跳帧开关,如果cpu解码能力不足,可以设置成5,否则
    // 会引起音视频不同步,也可以通过设置它来跳帧达到倍速播放
    [options setPlayerOptionIntValue:0 forKey:@"framedrop"];

    // 指定最大宽度
    [options setPlayerOptionIntValue:960 forKey:@"videotoolbox-max-frame-width"];

    // 自动转屏开关
    [options setFormatOptionIntValue:0 forKey:@"auto_convert"];

    // 重连次数
    [options setFormatOptionIntValue:1 forKey:@"reconnect"];

    // 超时时间,timeout参数只对http设置有效,若你用rtmp设置timeout,ijkplayer内部会忽略timeout参数。rtmp的timeout参数含义和http的不一样。
    [options setFormatOptionIntValue:30 * 1000 * 1000 forKey:@"timeout"];

    // 帧速率(fps) (确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
    [options setPlayerOptionIntValue:29.97 forKey:@"r"];
  • 直播设置
    //如果是rtsp协议,可以优先用tcp(默认是用udp)
    [options setFormatOptionValue:@"tcp" forKey:@"rtsp_transport"];
    //播放前的探测Size,默认是1M, 改小一点会出画面更快
    [options setFormatOptionIntValue:1024 * 16 forKey:@"probesize"];
    //播放前的探测时间
    [options setFormatOptionIntValue:50000 forKey:@"analyzeduration"];
    //软解码,更稳定
    [options setPlayerOptionIntValue:0 forKey:@"videotoolbox"];
    //解码参数,画面更清晰
    [options setCodecOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@"skip_loop_filter"];
    //
    [options setCodecOptionIntValue:IJK_AVDISCARD_DEFAULT forKey:@"skip_frame"];

    Boolean _isLive = true;
    if (_isLive) {
        // Param for living
        [options setPlayerOptionIntValue:3000 forKey:@"max_cached_duration"];   // 最大缓存大小是3秒,可以依据自己的需求修改
        [options setPlayerOptionIntValue:1 forKey:@"infbuf"];  // 无限读
        [options setPlayerOptionIntValue:0 forKey:@"packet-buffering"];  //  关闭播放器缓冲
    } else {
        // Param for playback
        [options setPlayerOptionIntValue:0 forKey:@"max_cached_duration"];
        [options setPlayerOptionIntValue:0 forKey:@"infbuf"];
        [options setPlayerOptionIntValue:1 forKey:@"packet-buffering"];
    }

5.本地通知

  • 添加本地通知
- (void)installMovieNotificationObservers {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(loadStateDidChange:)
                                                 name:IJKMPMoviePlayerLoadStateDidChangeNotification
                                               object:_player];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayBackFinish:)
                                                 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];

}
  • 移除本地通知
- (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];

}
  • 通过通知捕获播放状态
- (void)loadStateDidChange:(NSNotification*)notification {
    IJKMPMovieLoadState loadState = _player.loadState;

    if ((loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) {
        NSLog(@"LoadStateDidChange: IJKMovieLoadStatePlayThroughOK: %d\n",(int)loadState);
    }else if ((loadState & IJKMPMovieLoadStateStalled) != 0) {
        NSLog(@"loadStateDidChange: IJKMPMovieLoadStateStalled: %d\n", (int)loadState);
    } else {
        NSLog(@"loadStateDidChange: ???: %d\n", (int)loadState);
    }
}

- (void)moviePlayBackFinish:(NSNotification*)notification {
    int reason =[[[notification userInfo] valueForKey:IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
    switch (reason) {
        case IJKMPMovieFinishReasonPlaybackEnded:
            NSLog(@"playbackStateDidChange: IJKMPMovieFinishReasonPlaybackEnded: %d\n", reason);
            break;

        case IJKMPMovieFinishReasonUserExited:
            NSLog(@"playbackStateDidChange: IJKMPMovieFinishReasonUserExited: %d\n", reason);
            break;

        case IJKMPMovieFinishReasonPlaybackError:
            NSLog(@"playbackStateDidChange: IJKMPMovieFinishReasonPlaybackError: %d\n", reason);
            break;

        default:
            NSLog(@"playbackPlayBackDidFinish: ???: %d\n", reason);
            break;
    }
}

- (void)mediaIsPreparedToPlayDidChange:(NSNotification*)notification {
    NSLog(@"mediaIsPrepareToPlayDidChange\n");
}

- (void)moviePlayBackStateDidChange:(NSNotification*)notification {
    switch (_player.playbackState) {
        case IJKMPMoviePlaybackStateStopped:
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: stoped", (int)_player.playbackState);
            break;

        case IJKMPMoviePlaybackStatePlaying:
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: playing", (int)_player.playbackState);
            break;

        case IJKMPMoviePlaybackStatePaused:
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: paused", (int)_player.playbackState);
            break;

        case IJKMPMoviePlaybackStateInterrupted:
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: interrupted", (int)_player.playbackState);
            break;

        case IJKMPMoviePlaybackStateSeekingForward:
        case IJKMPMoviePlaybackStateSeekingBackward: {
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: seeking", (int)_player.playbackState);
            break;
        }

        default: {
            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: unknown", (int)_player.playbackState);
            break;
        }
    }
}

6.开始播放

// 启动预播放操作
[self.player prepareToPlay];
// 播放
[self.player play];

7.结束播放

[self.player shutdown];

实现效果

实现效果如图6-13所示

图6-13

results matching ""

    No results matching ""