如何開發出一款仿映客直播APP專案實踐篇 -【採集篇 】

發表於2016-12-09

【目錄】

【採集基本原理】

採集: 硬體(攝像頭)視訊影象
推流: 就是將採集到的音訊,視訊資料通過流媒體協議傳送到流媒體伺服器。

推流前的工作:採集,處理,編碼壓縮
推流中做的工作: 封裝,上傳

111929699-b0156485f733b0e3

推流前的工作

121929699-fadcf9db5cc15247

推流——採集到的音訊,視訊資料通過流媒體協議傳送到流媒體伺服器

【視訊採集】

– 方法一:利用封裝庫LFLiveKit(推薦)

– 方法二:利用系統庫AVFoundation

接下來,我會分別貼上兩種方法程式碼
其實 LFLiveKit 已經實現了 後臺錄製、美顏功能、支援h264、AAC硬編碼,動態改變速率,RTMP傳輸等,對AVFoundation庫進行了封裝,我們真正開發的時候直接使用就很方便啦。另外也有:
LiveVideoCoreSDK : 實現了美顏直播和濾鏡功能,我們只要填寫RTMP服務地址,直接就可以進行推流啦。
PLCameraStreamingKit: 也是一個不錯的 RTMP 直播推流 SDK。

雖然推薦用 LFLiveKit 已包含採集美顏編碼推流等功能,而為了進一步瞭解採集到推流完整過程,可以參觀方法二程式碼按自己的步子試著走走,詳細講解每個流程的原理。

方法一、利用LFLiveKit

xib上新增兩個Button 和一個Label (主要監聽連線狀態)

131929699-b8b648b99646b9a1

2.建立CaputuereLiveViewController.m類 註釋都寫在文件中

方法二、利用系統AVFoundation採集視訊

一、採集硬體(攝像頭)視訊影象

上述是大致實現獲取最基本資料的情況,一些細節(尺寸、方向)暫時沒有深入,真正做直播的時候,一般是視訊和音訊是分開處理的,只有重點注意那個代理方法。
二、GPUImage 處理

在進行編碼 H.264 之前,一般來說肯定會做一些美顏處理的,否則那播出的感覺太真實,就有點醜啦,在此以磨皮和美白為例簡單瞭解。(具體參考的是:琨君 基於 GPUImage 的實時美顏濾鏡
直接用 BeautifyFaceDemo 中的類 GPUImageBeautifyFilter
, 可以對的圖片直接進行處理:

但是視訊中是怎樣進行美容處理呢?怎樣將其轉換的呢?平常我們這樣直接使用:

此處用到了 GPUImageVideoCamera,可以大致瞭解下 GPUImage詳細解析(三)- 實時美顏濾鏡
GPUImageVideoCamera: GPUImageOutput的子類,提供來自攝像頭的影象資料作為源資料,一般是響應鏈的源頭。
GPUImageView:響應鏈的終點,一般用於顯示GPUImage的影象。
GPUImageFilter:用來接收源影象,通過自定義的頂點、片元著色器來渲染新的影象,並在繪製完成後通知響應鏈的下一個物件。
GPUImageFilterGroup:多個GPUImageFilter的集合。
GPUImageBeautifyFilter

141929699-36a5b529ce655c71

簡單理解這個美顏的流程

不得不說GPUImage 是相當強大的,此處的功能也只是顯現了一小部分,其中 filter 那塊的處理個人目前還有好多不理解,需要去深入瞭解啃原始碼,暫時不過多引入。通過這個過程將 sampleBuffer 美容處理後,自然是進行編碼啦。
三、視訊、音訊壓縮編碼

而編碼是用 硬編碼呢 還是軟編碼呢? 相同位元速率,軟編影象質量更清晰,但是耗電更高,而且會導致CPU過熱燙到攝像頭。不過硬編碼會涉及到其他平臺的解碼,有很多坑。綜合來說,iOS 端硬體相容性較好,iOS 8.0佔有率也已經很高了,可以直接採用硬編。
硬編碼:下面幾個DEMO 可以對比下,當然看 LFLiveKit 更直接。
VideoToolboxPlus
iOSHardwareDecoder
-VideoToolboxDemo
iOS-h264Hw-Toolbox

四、推流

封裝資料成 FLV,通過 RTMP 協議打包上傳,從主播端到服務端即基本完成推流。
4-1、封裝資料通常是封裝成 FLV
FLV流媒體格式是一種新的視訊格式,全稱為FlashVideo。由於它形成的檔案極小、載入速度極快,使得網路觀看視訊檔案成為可能,它的出現有效地解決了視訊檔案匯入Flash後,使匯出的SWF檔案體積龐大,不能在網路上很好的使用等缺點。
封包 FLV):一般FLV 檔案結構裡是這樣存放的:
[[Flv Header]
[Metainfo Tag]
[Video Tag]
[Audio Tag]
[Video Tag]
[Audio Tag]
[Other Tag]…]
其中 AudioTag 和 VideoTag 出現的順序隨機的,沒有嚴格的定義。Flv Header 是檔案的頭部,用FLV字串標明瞭檔案的型別,以及是否有音訊、視訊等資訊。之後會有幾個位元組告訴接下來的包位元組數。Metainfo 中用來描述Flv中的各種引數資訊,例如視訊的編碼格式、解析度、取樣率等等。如果是本地檔案(非實時直播流),還會有偏移時間戳之類的資訊用於支援快進等操作。VideoTag 存放視訊資料。對於H.264來說,第一幀傳送的NALU應為 SPS和PPS,這個相當於H.264的檔案頭部,播放器解碼流必須先要找到這個才能進行播放。之後的資料為I幀或P幀。AudioTag 存放音訊資料。對於AAC來說,我們只需要在每次硬編碼完成後給資料加上adts頭部資訊即可。
iOS 中的使用:詳細看看 LFLiveKit 中的 LFStreamRTMPSocket 類。

總的說來,這又是一個粗略的過程,站在好多個巨人的肩膀上,但是還是基本瞭解了一個推流的流程,沒有正式專案的經驗,肯定有太很多細節點忽略了和好多坑需要填,還是那個目的,暫時先作為自己的預備知識點吧,不過此處可以擴充套件和深入的知識點真的太多啦,如 LFLiveKitGPUImage 僅僅展露的是冰山一角。

程式碼地址:
gitHub : https://github.com/one-tea/ZKKLiveDemo

備註參考:
LiveVideoCoreSDK
LFLiveKit
GPUImage
LMLiveStreaming
PLCameraStreamingKit
iOS手機直播Demo技術簡介
iOS視訊開發經驗
iOS 上的相機捕捉
CMSampleBufferRef 與 UIImage 的轉換
GPUImage詳細解析(三)- 實時美顏濾鏡
iOS8系統H264視訊硬體編解碼說明
利用FFmpeg+x264將iOS攝像頭實時視訊流編碼為h264檔案
使用VideoToolbox硬編碼H.264
使用iOS自帶AAC編碼器
如何搭建一個完整的視訊直播系統?
直播中累積延時的優化
使用VLC做流媒體伺服器(直播形式)

gitHub程式碼地址:

Object-C版 : https://github.com/one-tea/ZKKLiveDemo
Swift版 : https://github.com/one-tea/ZKKLiveAPP_Swift3.0

相關文章