iOS視頻直播~推流、拉流原理

(轉(zhuǎn)帖著名出處:謝謝!)

首先說(shuō)下HLS協(xié)議:

  • 簡(jiǎn)單講就是把整個(gè)流分成一個(gè)個(gè)小的,基于 HTTP 的文件來(lái)下載,每次只下載一些,前面提到了用于 H5 播放直播視頻時(shí)引入的一個(gè) .m3u8 的文件,這個(gè)文件就是基于 HLS 協(xié)議,存放視頻流元數(shù)據(jù)的文件。

  • 每一個(gè) .m3u8 文件,分別對(duì)應(yīng)若干個(gè) ts 文件,這些 ts 文件才是真正存放視頻的數(shù)據(jù),m3u8 文件只是存放了一些 ts 文件的配置信息和相關(guān)路徑,當(dāng)視頻播放時(shí),.m3u8 是動(dòng)態(tài)改變的,video 標(biāo)簽會(huì)解析這個(gè)文件,并找到對(duì)應(yīng)的 ts 文件來(lái)播放,所以一般為了加快速度,.m3u8 放在 web 服務(wù)器上,ts 文件放在 cdn 上。

  • .m3u8 文件,其實(shí)就是以 UTF-8 編碼的 m3u 文件,這個(gè)文件本身不能播放,只是存放了播放信息的文本文件:

#EXTM3U                 m3u文件頭
#EXT-X-MEDIA-SEQUENCE   第一個(gè)TS分片的序列號(hào)
#EXT-X-TARGETDURATION   每個(gè)分片TS的最大的時(shí)長(zhǎng)
#EXT-X-ALLOW-CACHE      是否允許cache
#EXT-X-ENDLIST          m3u8文件結(jié)束符
#EXTINF                 指定每個(gè)媒體段(ts)的持續(xù)時(shí)間(秒),僅對(duì)其后面的URI有效mystream-12.ts

HLS 的請(qǐng)求流程是:

  • http 請(qǐng)求 m3u8 的 url。
  • 服務(wù)端返回一個(gè) m3u8 的播放列表,這個(gè)播放列表是實(shí)時(shí)更新的,一般一次給出5段數(shù)據(jù)的 url。
  • 客戶(hù)端解析 m3u8 的播放列表,再按序請(qǐng)求每一段的 url,獲取 ts 數(shù)據(jù)流。
Paste_Image.png

關(guān)于HLS延遲原因:

hls 協(xié)議是將直播流分成一段一段的小段視頻去下載播放的,所以假設(shè)列表里面的包含5個(gè) ts 文件,每個(gè) TS 文件包含5秒的視頻內(nèi)容,那么整體的延遲就是25秒。因?yàn)楫?dāng)你看到這些視頻時(shí),主播已經(jīng)將視頻錄制好上傳上去了,所以時(shí)這樣產(chǎn)生的延遲。當(dāng)然可以縮短列表的長(zhǎng)度和單個(gè) ts 文件的大小來(lái)降低延遲,極致來(lái)說(shuō)可以縮減列表長(zhǎng)度為1,并且 ts 的時(shí)長(zhǎng)為1s,但是這樣會(huì)造成請(qǐng)求次數(shù)增加,增大服務(wù)器壓力,當(dāng)網(wǎng)速慢時(shí)回造成更多的緩沖,所以蘋(píng)果官方推薦的ts時(shí)長(zhǎng)時(shí)10s,所以這樣就會(huì)大改有30s的延遲

視頻直播的整個(gè)流程:

  • 視頻錄制端:一般是電腦上的音視頻輸入設(shè)備或者手機(jī)端的攝像頭或者麥克風(fēng),目前以移動(dòng)端的手機(jī)視頻為主。

  • 視頻播放端:可以是電腦上的播放器,手機(jī)端的 native 播放器。

  • 視頻服務(wù)器端:一般是一臺(tái) nginx 服務(wù)器,用來(lái)接受視頻錄制端提供的視頻源,同時(shí)提供給視頻播放端流服務(wù)。

  • 簡(jiǎn)單流程

Paste_Image.png

數(shù)據(jù)采集原理:

下面將利用 ios 上的攝像頭,進(jìn)行音視頻的數(shù)據(jù)采集,主要分為以下幾個(gè)步驟:

  • 音視頻的采集,ios 中,利用 AVCaptureSession和AVCaptureDevice 可以采集到原始的音視頻數(shù)據(jù)流。
  • 對(duì)視頻進(jìn)行 H264 編碼,對(duì)音頻進(jìn)行 AAC 編碼,在 ios 中分別有已經(jīng)封裝好的編碼庫(kù)來(lái)實(shí)現(xiàn)對(duì)音視頻的編碼。
  • 對(duì)編碼后的音、視頻數(shù)據(jù)進(jìn)行組裝封包;
  • 建立 RTMP 連接并上推到服務(wù)端。
    ps:由于編碼庫(kù)大多使用 c 語(yǔ)言編寫(xiě),需要自己使用時(shí)編譯,對(duì)于 ios,可以使用已經(jīng)編譯好的編碼庫(kù)。
    x264編碼:https://github.com/kewlbear/x264-ios(復(fù)制此鏈接到瀏覽器打開(kāi))
    faac編碼:https://github.com/fflydev/faac-ios-build(操作同上)
    ffmpeg編碼:https://github.com/kewlbear/FFmpeg-iOS-build-script(操作同上)
    關(guān)于如果想給視頻增加一些特殊效果,例如增加濾鏡等,一般在編碼前給使用濾鏡庫(kù),但是這樣也會(huì)造成一些耗時(shí),導(dǎo)致上傳視頻數(shù)據(jù)有一定延時(shí)。

RTMP介紹:

Real Time Messaging Protocol(簡(jiǎn)稱(chēng) RTMP)是 Macromedia 開(kāi)發(fā)的一套視頻直播協(xié)議。和 HLS 一樣都可以應(yīng)用于視頻直播,區(qū)別是 RTMP 基于 flash 無(wú)法在 ios 的瀏覽器里播放,但是實(shí)時(shí)性比 HLS 要好。所以一般使用這種協(xié)議來(lái)上傳視頻流,也就是視頻流推送到服務(wù)器。
對(duì)比:

  • RTMP 首先就是延遲低,基于TCP的長(zhǎng)鏈接,對(duì)于數(shù)據(jù)處理及時(shí),收到即刻發(fā)送,推薦使用場(chǎng)景:即時(shí)互動(dòng)。
  • HLS 延遲高,短鏈接,原理是集合了一段時(shí)間的視頻數(shù)據(jù),切割ts片,逐個(gè)下載播放。優(yōu)點(diǎn)是跨平臺(tái)。

推流:

推流,就是將我們已經(jīng)編碼好的音視頻數(shù)據(jù)發(fā)往視頻流服務(wù)器中,一般常用的是使用 rtmp 推流,可以使用第三方庫(kù) librtmp-iOS 進(jìn)行推流,librtmp 封裝了一些核心的 api 供使用者調(diào)用,如果覺(jué)得麻煩,可以使用現(xiàn)成的 ios 視頻推流sdk,也是基于 rtmp 的。具體說(shuō)下:
也就是對(duì)編碼好的音視頻數(shù)據(jù)推到服務(wù)器上,這里我們又分為兩類(lèi)推流模式:手機(jī)端推流,服務(wù)器本地推流。就拿我上一家公司的電視直播來(lái)說(shuō),視頻源是來(lái)自電視臺(tái)的,需要通過(guò)ffmpeg命令來(lái)進(jìn)行個(gè)推流,那么推流協(xié)議的話(huà)這里又分為了:HLS推流和rtmp推流,這里的取舍主要涉及到了是否需要及其實(shí)時(shí)的直播問(wèn)題,也就是延遲20 30s是否接受,當(dāng)然電視直播并不是主播實(shí)時(shí)互動(dòng),所以不需要使用實(shí)時(shí)流媒體協(xié)議的rtmp,所以通過(guò)ffmpeg -loglevel 這么一個(gè)命令將電視臺(tái)給的視頻進(jìn)行各像nginx服務(wù)器的一個(gè)推流,那么我們就可以通過(guò)nginx服務(wù)器給的鏈接,配合我的第三方的直播框架,就可以實(shí)現(xiàn)個(gè)直播,這個(gè)是服務(wù)器本地的HLS協(xié)議的一個(gè)推流。當(dāng)然如果我們要做一個(gè)沒(méi)有延遲的比如實(shí)現(xiàn)各主播互動(dòng)的一個(gè)直播,那么就是iOS客戶(hù)端用rtmp協(xié)議的一個(gè)往nginx服務(wù)器的一個(gè)推流了。在iOS設(shè)備上進(jìn)行各推流的話(huà),是通過(guò)AVCaptureSession這么一個(gè)捕捉會(huì)話(huà),指定兩個(gè)AVCaptureDevice 也就是iOS的攝像頭和麥克風(fēng),獲取個(gè)原始視頻和音頻,然后需要進(jìn)行個(gè)H.264的視頻編碼和AAC的音頻編碼,再將編碼后的數(shù)據(jù)整合成一個(gè)音視頻包,通過(guò)rmtp推送到nginx服務(wù)器。這里這些步驟,我們可以通過(guò)各第三方集成好的推流工具進(jìn)行推流,這個(gè)工具有l(wèi)ibrtmp,和騰訊的GDLiveStreaming進(jìn)行個(gè)推流。

由于時(shí)間匆忙~內(nèi)容寫(xiě)的不是很深入,后續(xù)有時(shí)間會(huì)回來(lái)更新...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容