一.簡述總體內容
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拉流),也可以用自己寫的播放軟件來拉流,或者三方

手動輸入命令的時候容易出現了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文件所在位置

通過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時間就要長一點了. 如果速度過慢, 建議翻牆. 不過也才50多M的東西, 耐心一點就好. 等待的時間裡, 再安裝一個支持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

效果如下

上面的總結的大神的文章
四.簡單的集成推流拉流(實用篇)
1. 推流端,這裡我才用的 開源的推流框架,開源的iOS推流框架LFLiveKit. 是用OC寫的, 很適合學習集成也非常簡單, 幾句代碼就OK了.
采用cocopods導入即可
pod 'LFLiveKit'
提示:LFLiveKit已經集成了GPUImage, 如果項目中有集成GPUImage, 需要將之前的移除掉. 且集成LFLiveKit需要關閉Bitcode.
集成LFLiveKit需要關閉Bitcode.導入成功

在推流的控制器寫入下面的代碼
導入推流框架 #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;到此推流就成功了,提示網絡一定要打來

2. 拉流端 主要是基於ijkplayer 的. 最好是打包成framework. 打包教程
下載 ijkplayer打包好的靜態庫 密碼: mcjt
導入庫:

完成上述之後,運行不報錯,就說明你基本上成功了,在拉流的控制器裡面輸入下面的代碼
導入 #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

到此,推流和拉流就完成了,更多美顏等功能等等,就看更多的大神博客,下面推薦
五.好的直播博客推薦
大神博客1
大神博客2
七牛雲技術(三方直播)
最詳細的直播
ijkplayer視頻直播框架(最好打包成靜態庫):可以進去學習一下
RTMP快速集成
推流框架