iOS 本地nginx LFLiveKit IJKPlayer的一系列直播推流拉流操作

1.nginx rtmp本地推流拉流服务器搭建
1.1 安装 (没安装brew的同学,阔以看下这篇文章http://blog.csdn.net/wdd1324/article/details/72769789)

 sudo brew install nginx

1.2 查看版本号

nginx -v

安装成功则返回 nginx version: nginx/1.12.2
1.3 启动nginx

sudo nginx

如果报错

nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)

这个是端口被占用,我们可以杀死其他占用该端口号的进程或者在nginx.conf里修改端口号
先说杀死一个进程的方法,后面会说到修改nginx.conf

sudo lsof -i tcp:8080

然后找到PID值,再kill掉该进程

kill PID

再次启动 nginx
启动成功
打开浏览器 输入http://localhost:8080 出现以下界面则成功


1.4 配置nginx
打开终端 cd到nginx目录下

cd /usr/local/etc/nginx

运行vim 打开nginx.conf

vim nginx.conf

配置rtmp (这里可以不用做配置,直接用一个端口就能实现推拉,推拉都为同一个端口)
listen为监听的端口号,192.168.4.205是我本地的ip地址,我用一个src作为推流地址,一个des作为拉流地址,用ffmpeg将输入源接入输出源,360x480为输出的分辨率

rtmp {

    server {

        listen 8080;

        chunk_size 4000;

# TV mode: one publisher, many subscribers
        application src {

# enable live streaming
            live on;
            interleave on;
            wait_key on;

# publish only from localhost
            allow publish all;
#deny publish all;

            allow play all;
 exec /usr/local/opt/ffmpeg/bin/ffmpeg  -i rtmp://192.168.4.205:8080/src -vcodec libx264 -vprofile main -tune zerolatency -s 360x480 -pix_fmt yuv420p -movflags +faststart -preset ultrafast  -f flv rtmp://192.168.4.205:8080/des;
        }
        application des {
            live on;
            interleave on;
            wait_key on;
        }
    }
}

1.5 重启nginx

sudo nginx -s reload

这样就OK啦,可以在mac上通过OBS来推流,VLC来拉流测试是否成功。

1.6 其他命令与问题
关闭nginx

sudo nginx -s stop

2.使用LFLiveKit来推流(采用的是h264视频编码,ACC的音频硬编码)
2.1用Pods来添加LFLiveKit

pod 'LFLiveKit'

2.2LFLiveSession初始化
设置视频图像的分辨率

    LFLiveVideoConfiguration *config = [LFLiveVideoConfiguration defaultConfigurationForQuality:LFLiveVideoQuality_Low1];
    config.videoSize = CGSizeMake(360, 512);   //图片分辨率

初始化session

    _session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfigurationForQuality:LFLiveAudioQuality_Low] videoConfiguration:config captureType:LFLiveCaptureMaskVideo];
    _session.preView= self.livingPushView;    //推流预览
    _session.captureDevicePosition = AVCaptureDevicePositionUnspecified;    //设置为后置摄像头,默认为前置摄像头
    _session.beautyFace = NO;    //是否美颜
    _session.running = YES;    //是否播放(默认为NO的,不添加则无预览图像)
    _session.delegate = self;    //设置代理

2.3LFLive的代理方法
根据代理可以查看到推流状态

- (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange:(LFLiveState)state {
    switch (state) {
        case LFLiveReady: {
            NSLog(@"-准备");
        }
            break;
        case LFLivePending: {
            NSLog(@"-连接中");
        }
            break;
        case LFLiveStart: {
            NSLog(@"-已连接");
        }
            break;
        case LFLiveStop: {
            NSLog(@"-已断开");
        }
            break;
        case LFLiveError: {
            NSLog(@"-连接出错");
        }
            break;
        case LFLiveRefresh: {
            NSLog(@"-正在刷新");
        }
            break;
        default:
            break;
    }
}

2.4 开始推流

    LFLiveStreamInfo *stream = [LFLiveStreamInfo new];
    stream.url = @"rtmp://192.168.4.205:8080/src";
    [self.session startLive:stream];

界面消失的时候停止推流

    [self.session stopLive];

下面我们看一下拉流

  1. IJKPlayer
    3.1IJKMediaFramework集成
    大家阔以看下这片文章,写得很详细
    http://www.jianshu.com/p/1f06b27b3ac0
    3.2 IJKMediaFramework集成成功后,在使用的地方导入
    #import 
    #import 
    #import 

3.3 配置IJKFFOptions

    IJKFFOptions *options = [IJKFFOptions optionsByDefault];
    [options setPlayerOptionValue:@"1" forKey:@"an"];  //静音设置
    [options setPlayerOptionValue:@"1" forKey:@"videotoolbox"];  //开启硬解码
    [options setPlayerOptionIntValue:10 forKey:@"max-buffer-size"];  //最大缓存
    [options setFormatOptionIntValue:10 forKey:@"rtbufsize"];   //缓存
    [options setFormatOptionIntValue:2000000 forKey:@"analyzeduration"]; 
    [options setFormatOptionValue:@"nobuffer" forKey:@"fflags"];
    [options setFormatOptionIntValue:4096 forKey:@"probsize"];

这是楼主的一些配置参数。
3.4 IJKFFMoviePlayerController初始化

    self.player = [[IJKFFMoviePlayerController alloc] initWithContentURLString:_ipstring2 withOptions:options];        
    self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    self.player.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  
    self.player.view.backgroundColor = [UIColor blackColor];
    self.player.scalingMode = IJKMPMovieScalingModeAspectFill; //缩放模式
    self.player.shouldAutoplay = YES; //开启自动播放(player准后后,自动播放)
    [self.view addSubview:self.player.view];// 添加拉流预览视图
    [self.player prepareToPlay];

3.5 添加观察者,监听拉流状态

    //监听网络状态改变
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadStateDidChange:) name:IJKMPMoviePlayerLoadStateDidChangeNotification object:self.player];
    //监听播放网络状态改变
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playStateDidChange:) name:IJKMPMoviePlayerPlaybackStateDidChangeNotification object:self.player];
//网络状态改变通知响应
- (void)loadStateDidChange:(NSNotification *)notification{
    IJKMPMovieLoadState loadState = self.player.loadState;
    if ((loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) {
        NSLog(@"LoadStateDidChange: 可以开始播放的状态: %d\n",(int)loadState);
    }else if ((loadState & IJKMPMovieLoadStateStalled) != 0) {
        NSLog(@"loadStateDidChange: IJKMPMovieLoadStateStalled: %d\n", (int)loadState);
    } else {
        NSLog(@"loadStateDidChange: ???: %d\n", (int)loadState);
    }
}
//播放状态改变通知响应
- (void)playStateDidChange:(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;
        }
    }
}

3.6 界面消失的时候,关闭播放器
[self.player stop];
[self.player shutdown];

你可能感兴趣的:(iOS 本地nginx LFLiveKit IJKPlayer的一系列直播推流拉流操作)