iOS 直播实用篇 (手把手教)

2,704 阅读8分钟
原文链接: www.jianshu.com

一.简述总体内容

  • 1.直播流程介绍
  • 2.Mac搭建nginx+rtmp服务器(模拟推流拉流)
  • 3.简单的集成推流拉流(实用篇)
  • 4.好的博客推荐

二.直播流程介绍

  • 1.简单的流程图


    简单的流程图
  • 2.七牛的直播流程


    七牛的直播流程
  • 3.视频直播,可以分为采集,前处理(美颜等等),编码,推流和传输,服务器处理,解码拉流

    • 1.采集:采集是整个视频推流过程中的第一个环节,它从系统的采集设备中获取原始视频数据,将其输出到下一个环节。视频的采集涉及两方面数据的采集:音频采集和图像采集,它们分别对应两种完全不同的输入源和数据格式.iOS系统因为软硬件种类不多, 硬件适配性比较好, 所以比较简单. 而Android端市面上机型众多, 要做些机型的适配工作.PC端是最麻烦的, 各种奇葩摄像头驱动.所以现在很多的中小型直播平台, 都放弃了PC的直播, 更有一些直播平台只做iOS端的视频直播.
      七🐂对采集的理解


      采集
      • 2.前处理: 美颜算法,视频的模糊效果, 水印等都是在这个环节做. 目前iOS端最著名开源框架的毫无疑问就是GPUImage.其中内置了125种渲染效果, 还支持各种脚本自定义.GPUImage所有滤镜介绍都说「80% 的主播没有美颜根本没法看」,美颜是直播产品中最常见的功能之一。最近准备在香港上市的美图公司的主打产品就是美颜相机和美拍,有媒体戏称其会冲击化妆品行业,其实就是美颜的效果的功劳,让美女主播们不化妆也可以自信的直播,而美颜相机的用户则可以拍出「更好的自己」。
        袁睁大神对美颜的理解
        七牛对前处理的理解


        前处理
      • 3.编码:对流媒体传输来说,编码也非常重要,它的编码性能、编码速度和编码压缩比会直接影响整个流媒体传输的用户体验和传输成本.重难点在于要在分辨率,帧率,码率,GOP等参数设计上找到最佳平衡点。iOS8之后, Apple开放了VideoToolbox.framework, 可以直接进行硬编解码, 这也是为什么现在大多数直播平台最低只支持到iOS8的原因之一. iOS端硬件兼容性比较好, 可以直接采取硬编码,常用的编码有:H265
        七牛对编码的理解

      • 4.推流和传输: 这块一般都是交给CDN服务商. CDN只提供带宽和服务器之间的传输, 发送端和接收端的网络连接抖动缓存还是要自己实现的.目前国内最大的CDN服务商应该是网宿.传输协议一般是RTMP,HLS,FLV
        七牛对传输和推流的理解

      • 5.服务器处理:需要在服务器做一些流处理工作, 让推送上来的流适配各个平台各种不同的协议, 比如:RTMP,HLS,FLV...
        RTMP、RTSP、HTTP视频协议详解

      • 6.解码拉流:推流需要编码,同样拉流解码是必须的. iOS端兼容较好,Android依然大坑.这块的难点在于音画同步, 目前很多直播平台这块是硬伤.国内比较好的开源项目应该是B站开源的ijkplayer .斗鱼就是基于ijkplayer 的, 本项目也是基于ijkplayer 的.

      • 7.七牛对延迟优化的处理

      • 8.七牛的现代播放原理

      • 9.直播云 SDK 性能测试模型

三.Mac搭建nginx+rtmp服务器(模拟推流拉流)

效果如下(把桌面的视频推到搭建的服务器再利用播放器VLC 密码: 7gbp拉流),也可以用自己写的播放软件来拉流,或者三方


Mac搭建nginx+rtmp服务器(模拟推流拉流)

手动输入命令的时候容易出现了bug(所以, 建议大家直接复制命令, 不要手动输入命令). 所以记录一份详细的搭建步骤,参考Mac搭建nginx+rtmp服务器

  • 1.打开终端, 查看是否已经安装了Homebrew, 直接终端输入命令

       man brew

    如果Mac已经安装了, 会显示一些命令的帮助信息. 此时输入Q退出即可, 直接进入第二步.反之, 如果没有安装,执行命令

      ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    如果安装后, 想要卸载

      ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
  • 2.安装nginx

    先clone nginx项目到本地

      brew tap homebrew/nginx

    执行安装:

      brew install nginx-full --with-rtmp-module

    此时, nginx和rtmp模块就安装好了
    输入命令:

      nginx

    在浏览器里打开http://localhost:8080
    如果出现下图, 则表示安装成功


    安装成功

    如果终端上提示

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

    则表示8080端口被占用了, 查看端口PID

      lsof -i tcp:8080

    根据端口PID, kill掉(这儿的9603换成你自己8080端口的PID)

      kill 9603

    然后重新执行nginx, 打开http://localhost:8080 进行检测是否 nginx安装成功

  • 3.配置nginx和ramp

    首先我们查看nginx安装到哪了

      brew info nginx-full

    如图, 找到nginx.conf文件所在位置


    nginx.conf文件所在位置

通过vim或者点击Finder->前往->前往文件夹->输入/usr/local/etc/nginx/nginx.conf->用记事本工具(推荐Sublime Text)打开nginx.conf.

直接滚到最后一行, 在最后一个}(即最后的空白处, 没有任何{})后面添加

  # 在http节点后面加上rtmp配置:
  rtmp {
    server {
    listen 1935;
    application rtmplive {
        live on;
        record off;
      }
    }
 }

记得保存command+S

然后重启nginx(其中的1.10.1要换成你自己安装的nginx版本号, 查看版本号用nginx -v命令即可)

  /usr/local/Cellar/nginx-full/1.10.1/bin/nginx -s reload
  • 4.安装ffmpeg
    执行命令

     brew install ffmpeg

    安装ffmpeg时间就要长一点了. 如果速度过慢, 建议翻墙. 不过也才50M的东西, 耐心一点就好. 等待的时间里, 再安装一个支持rtmp协议的视频播放器VLC 密码: 7gbp

  • 5.进行推流

    (1).ffmpeg推流,用我桌面的一个动画片为例,执行推流命令


动画片

ffmpeg -re -i /Users/jinqianxiang/Desktop/BigBuck.m4v -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/rtmplive/room

提醒: /Users/jinqianxiang/Desktop/BigBuck.m4v是路径,你可把视频拖进终端,查看路径

将视频推流到服务器后,打开VLC,然后File->open network->输入:

  rtmp://localhost:1935/rtmplive/room

输入拉流的url

效果如下


效果

上面的总结的大神的文章

四.简单的集成推流拉流(实用篇)

  • 1. 推流端,这里我才用的 开源的推流框架,开源的iOS推流框架LFLiveKit. 是用OC写的, 很适合学习集成也非常简单, 几句代码就OK了.

    采用cocopods导入即可

    pod 'LFLiveKit'

提示:LFLiveKit已经集成了GPUImage, 如果项目中有集成GPUImage, 需要将之前的移除掉. 且集成LFLiveKit需要关闭Bitcode.


集成LFLiveKit需要关闭Bitcode.

导入成功


cocopods成功导入LFLiveKit

在推流的控制器写入下面的代码

导入推流框架 #import "LFLiveKit.h"

- (LFLiveSession*)session {
if (!_session) {
    _session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
    _session.preView = self;
    _session.delegate = self;
  }
  return _session;
}

- (void)startLive { 
    LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];
    streamInfo.url = @"your server rtmp url";
    [self.session startLive:streamInfo];
}

- (void)stopLive {
      [self.session stopLive];
}

//MARK: - CallBack:
- (void)liveSession:(nullable LFLiveSession *)session liveStateDidChange: (LFLiveState)state;
- (void)liveSession:(nullable LFLiveSession *)session debugInfo:(nullable LFLiveDebug*)debugInfo;
- (void)liveSession:(nullable LFLiveSession*)session errorCode:(LFLiveSocketErrorCode)errorCode;

到此推流就成功了,提示网络一定要打来


打开网络

导入库

完成上述之后,运行不报错,就说明你基本上成功了,在拉流的控制器里面输入下面的代码

导入 #import 

 1.创建推流对象
 - (LFLiveSession*)session {
     if (!_session) {
    _session = [[LFLiveSession alloc] initWithAudioConfiguration:[LFLiveAudioConfiguration defaultConfiguration] videoConfiguration:[LFLiveVideoConfiguration defaultConfiguration]];
    _session.delegate = self;
  }
  return _session;
}

2.在点击开始直播的方法里面输入

     NSLog(@"开始直播");

// 判断是否是模拟器
if ([[UIDevice deviceVersion] isEqualToString:@"iPhone Simulator"]) {

    [MBProgressHUD showError:@"请用真机进行测试, 此模块不支持模拟器测试"];

    return;
}

// 判断是否有摄像头
if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
    [MBProgressHUD showError:@"您的设备没有摄像头或者相关的驱动, 不能进行直播"];
    return;
}

// 判断是否有摄像头权限
AVAuthorizationStatus  authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authorizationStatus == AVAuthorizationStatusRestricted|| authorizationStatus == AVAuthorizationStatusDenied) {
    [MBProgressHUD showError:@"app需要访问您的摄像头。\n请启用摄像头-设置/隐私/摄像头"];

    return;
}

// 开启麦克风权限
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
    [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
        if (granted) {
            return YES;
        }
        else {
            //[self showInfo:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风"];
            return NO;
        }
    }];
}

LFLiveStreamInfo *streamInfo = [LFLiveStreamInfo new];

streamInfo.url = kTRMPServe;

[self.session startLive:streamInfo];

相关的类demo里面都有简单的直播demo 密码: w935


屏幕快照 2016-11-09 上午12.27.36.png

到此,推流和拉流就完成了,更多美颜等功能等等,就看更多的大神博客,下面推荐

五.好的直播博客推荐

大神博客1
大神博客2
七牛云技术(三方直播)
最详细的直播
ijkplayer视频直播框架(最好打包成静态库):可以进去学习一下
RTMP快速集成
推流框架