音视频
直播音視頻流(小解)
1.基礎(chǔ)背景知識(shí)
2.視音頻編碼封裝過程
3.對(duì)比sdl等視音頻播放庫(kù)
4.對(duì)比f(wàn)fmeg
5.rtmp rtsp hls簡(jiǎn)介
下面是系統(tǒng)框架圖
基礎(chǔ)知識(shí):我們?nèi)庋劭梢姷牧鲿扯葹?5幀每秒每一幀有很多很像素組成
所以每幀圖像視作一個(gè)三維矩陣—RGB
分辨率:即一個(gè)平面內(nèi)像素的數(shù)量。通常表示成寬*高
將視頻定義為在單位時(shí)間內(nèi)連續(xù)的 n 幀,這可以視作一個(gè)新的維度,n 即為幀率,若單位時(shí)間為秒,則等同于 FPS (每秒幀數(shù) Frames Per Second)。
利用視覺特性:和區(qū)分顏色相比,我們區(qū)分亮度要更加敏銳。時(shí)間上的重復(fù):一段視頻包含很多只有一點(diǎn)小小改變的圖像。圖像內(nèi)的重復(fù):每一幀也包含很多顏色相同或相似的區(qū)域。(YUV)
I 幀(幀內(nèi)編碼,關(guān)鍵幀) 是一個(gè)自足的幀。它不依靠任何東西來渲染,I 幀與靜態(tài)圖片相似。第一幀通常是 I 幀,但我們將看到 I 幀被定期插入其它類型的幀之間。
P 幀(預(yù)測(cè))P 幀利用了一個(gè)事實(shí):當(dāng)前的畫面幾乎總能使用之前的一幀進(jìn)行渲染。例如,在第二幀,唯一的改變是球向前移動(dòng)了。僅僅使用(第二幀)對(duì)前一幀的引用和差值,我們就能重建前一幀
編碼方式可以分為幀內(nèi)編碼和幀間編碼。
內(nèi)編碼方式:
即只利用了單幀圖像內(nèi)的空間相關(guān)性,對(duì)冗余數(shù)據(jù)進(jìn)行編碼,達(dá)到壓縮效果,而沒有利用時(shí)間相關(guān)性,不使用運(yùn)動(dòng)補(bǔ)償。所以單靠自己,便能完整解碼出一幀畫面。
幀間編碼:
由于視頻的特性,相鄰的幀之間其實(shí)是很相似的,通常是運(yùn)動(dòng)矢量的變化。利用其時(shí)間相關(guān)性,可以通過參考幀運(yùn)動(dòng)矢量的變化來預(yù)測(cè)圖像,并結(jié)合預(yù)測(cè)圖像與原始圖像的差分,便能解碼出原始圖像。所以,幀間編碼需要依賴其他幀才能解碼出一幀畫面。
由于編碼方式的不同,視頻中的畫面幀就分為了不同的類別,其中包括:I 幀、P 幀、B 幀。
I 幀(Intra coded frames):
I 幀圖像采用幀I 幀使用幀內(nèi)壓縮,不使用運(yùn)動(dòng)補(bǔ)償,由于 I 幀不依賴其它幀,可以獨(dú)立解碼。I 幀圖像的壓縮倍數(shù)相對(duì)較低,周期性出現(xiàn)在圖像序列中的,出現(xiàn)頻率可由編碼器選擇。
P 幀(Predicted frames):
P 幀采用幀間編碼方式,即同時(shí)利用了空間和時(shí)間上的相關(guān)性。P 幀圖像只采用前向時(shí)間預(yù)測(cè),可以提高壓縮效率和圖像質(zhì)量。P 幀圖像中可以包含幀內(nèi)編碼的部分,即 P 幀中的每一個(gè)宏塊可以是前向預(yù)測(cè),也可以是幀內(nèi)編碼。
B 幀(Bi-directional predicted frames):
B 幀圖像采用幀間編碼方式,且采用雙向時(shí)間預(yù)測(cè),可以大大提高壓縮倍數(shù)。也就是其在時(shí)間相關(guān)性上,還依賴后面的視頻幀,也正是由于 B 幀圖像采用了后面的幀作為參考,因此造成視頻幀的傳輸順序和顯示順序是不同的。
也就是說,一個(gè) I 幀可以不依賴其他幀就解碼出一幅完整的圖像,而 P 幀、B 幀不行。P 幀需要依賴視頻流中排在它前面的幀才能解碼出圖像。B 幀則需要依賴視頻流中排在它前面或后面的I/P幀才能解碼出圖像。
對(duì)于I幀和P幀,其解碼順序和顯示順序是相同的,但B幀不是,如果視頻流中存在B幀,那么就會(huì)打算解碼和顯示順序。
正因?yàn)榻獯a和顯示的這種非線性關(guān)系,所以需要DTS、PTS來標(biāo)識(shí)幀的解碼及顯示時(shí)間。
時(shí)間戳DTS、PTS (實(shí)現(xiàn)視音頻同步)
DTS(Decoding Time Stamp):即解碼時(shí)間戳,這個(gè)時(shí)間戳的意義在于告訴播放器該在什么時(shí)候解碼這一幀的數(shù)據(jù)。
PTS(Presentation Time Stamp):即顯示時(shí)間戳,這個(gè)時(shí)間戳用來告訴播放器該在什么時(shí)候顯示這一幀的數(shù)據(jù)。
當(dāng)視頻流中沒有 B 幀時(shí),通常 DTS 和 PTS 的順序是一致的。但如果有 B 幀時(shí),就回到了我們前面說的問題:解碼順序和播放順序不一致了,即視頻輸出是非線性的。
比如一個(gè)視頻中,幀的顯示順序是:I B B P,因?yàn)锽幀解碼需要依賴P幀,因此這幾幀在視頻流中的順序可能是:I P B B,這時(shí)候就體現(xiàn)出每幀都有 DTS 和 PTS 的作用了。DTS 告訴我們?cè)摪词裁错樞蚪獯a這幾幀圖像,PTS 告訴我們?cè)摪词裁错樞蝻@示這幾幀圖像
視頻壓縮標(biāo)準(zhǔn):
計(jì)算每秒 30 幀,每像素 24 bit,分辨率是 480x240 的視頻需要多少帶寬嗎?沒有壓縮時(shí)是 82.944 Mbps 只能靠視頻編解碼器。怎么做?
H.261 誕生在 1990(技術(shù)上是 1988),被設(shè)計(jì)為以 64 kbit/s 的數(shù)據(jù)速率工作。它已經(jīng)使用如色度子采樣、宏塊,等等理念。在 1995 年,H.263 視頻編解碼器標(biāo)準(zhǔn)被發(fā)布,并繼續(xù)延續(xù)到 2001 年。
在 2003 年 H.264/AVC 的第一版被完成。在同一年,一家叫做 TrueMotion 的公司發(fā)布了他們的免版稅有損視頻壓縮的視頻編解碼器,稱為 VP3。在 2008 年,Google 收購(gòu)了這家公司,在同一年發(fā)布 VP8。在 2012 年 12 月,Google 發(fā)布了 VP9,市面上大約有 3/4 的瀏覽器(包括手機(jī))支持。
AV1 是由 Google, Mozilla, Microsoft, Amazon, Netflix, AMD, ARM, NVidia, Intel, Cisco 等公司組成的開放媒體聯(lián)盟(AOMedia)設(shè)計(jì)的一種新的視頻編解碼器,免版稅,開源。第一版 0.1.0 參考編解碼器發(fā)布于 2016 年 4 月 7 號(hào)。
DTS 和 PTS
DTS(Decoding Time Stamp, 解碼時(shí)間戳),表示壓縮幀的解碼時(shí)間。
PTS(Presentation Time Stamp, 顯示時(shí)間戳),表示將壓縮幀解碼后得到的原始幀的顯示時(shí)間。
音頻中 DTS 和 PTS 是相同的。視頻中由于 B 幀需要雙向預(yù)測(cè),B 幀依賴于其前和其后的幀,因此含 B 幀的視頻解碼順序與顯示順序不同,即 DTS 與 PTS 不同。當(dāng)然,不含 B 幀的視頻,其 DTS 和 PTS 是相同的
第一步 - 圖片分區(qū)
第一步是將幀分成幾個(gè)分區(qū),子分區(qū)甚至更多。
微小移動(dòng)的部分使用較小的分區(qū),而在靜態(tài)背景上使用較大的分區(qū)
第二步 - 預(yù)測(cè)
一旦我們有了分區(qū),我們就可以在它們之上做出預(yù)測(cè)。對(duì)于幀間預(yù)測(cè),我們需要發(fā)送運(yùn)動(dòng)向量和殘差;至于幀內(nèi)預(yù)測(cè),我們需要發(fā)送預(yù)測(cè)方向和殘差。
第三步 - 轉(zhuǎn)換
在我們得到殘差塊(預(yù)測(cè)分區(qū)-真實(shí)分區(qū))之后,我們可以用一種方式變換它,這樣我們就知道哪些像素我們應(yīng)該丟棄,還依然能保持整體質(zhì)量。這個(gè)確切的行為有幾種變換方式。
?將像素塊轉(zhuǎn)換為相同大小的頻率系數(shù)塊。
?壓縮能量,更容易消除空間冗余。
?可逆的,也意味著你可以還原回像素。
第四步 - 量化
當(dāng)我們丟棄一些系數(shù)時(shí),在最后一步(變換),我們做了一些形式的量化。這一步,我們選擇性地剔除信息(有損部分)或者簡(jiǎn)單來說,我們將量化系數(shù)以實(shí)現(xiàn)壓縮。
第五步 - 熵編碼
(無損壓縮算法都是熵編碼算法)
熵編碼就是根據(jù)數(shù)據(jù)中不同字符出現(xiàn)的概率,用不同長(zhǎng)度的編碼來表示不同字符。出現(xiàn)概率越高的字符,則用越短的編碼表示;出現(xiàn)概率低的字符,可以用比較長(zhǎng)的編碼表示
在我們量化數(shù)據(jù)(圖像塊/切片/幀)之后,我們?nèi)匀豢梢砸詿o損的方式來壓縮它。有許多方法(算法)可用來壓縮數(shù)據(jù)。
VLC 編碼
我們壓縮 eat符號(hào)流,假設(shè)我們?yōu)槊總€(gè)字符花費(fèi) 8 bit,在沒有做任何壓縮時(shí)我們將花費(fèi) 24 bit。但是在這種情況下,我們使用各自的代碼來替換每個(gè)字符,我們就能節(jié)省空間
第一步是編碼字符 e 為 10,第二個(gè)字符是 a,追加(不是數(shù)學(xué)加法)后是 [10][0],最后是第三個(gè)字符 t,最終組成已壓縮的比特流 [10][0][1110] 或 1001110,這只需 7 bit(比原來的空間少 3.4 倍)。
算術(shù)編碼
讓我們假設(shè)我們有一個(gè)符號(hào)流:a, e, r, s 和 t,它們的概率由下表所示。
aerst概率0.30.30.150.050.2考慮到這個(gè)表,我們可以構(gòu)建一個(gè)區(qū)間,區(qū)間包含了所有可能的字符,字符按出現(xiàn)概率排序。
讓我們編碼 eat 流,我們選擇第一個(gè)字符 e 位于 0.3 到 0.6 (但不包括 0.6)的子區(qū)間,我們選擇這個(gè)子區(qū)間,按照之前同等的比例再次分割。
讓我們繼續(xù)編碼我們的流 eat,現(xiàn)在使第二個(gè) a 字符位于 0.3 到 0.39 的區(qū)間里,接著再次用同樣的方法編碼最后的字符 t,得到最后的子區(qū)間 0.354 到 0.372。
我們只需從最后的子區(qū)間 0.354 到 0.372 里選擇一個(gè)數(shù),讓我們選擇 0.36,不過我們可以選擇這個(gè)子區(qū)間里的任何數(shù)。僅靠這個(gè)數(shù),我們將可以恢復(fù)原始流 eat。就像我們?cè)趨^(qū)間的區(qū)間里畫了一根線來編碼我們的流。
編碼器和解碼器都必須知道字符概率表,因此,你也需要傳送這個(gè)表。
第六步 - 比特流格式
完成所有這些步之后,我們需要將壓縮過的幀和內(nèi)容打包進(jìn)去。需要明確告知解碼器編碼定義,如顏色深度,顏色空間,分辨率,預(yù)測(cè)信息(運(yùn)動(dòng)向量,幀內(nèi)預(yù)測(cè)方向),配置,層級(jí),幀率,幀類型,幀號(hào)等等更多信息
幀間和幀內(nèi)預(yù)測(cè),轉(zhuǎn)換,量化,熵編碼和其它
HEVC(h.265) 比 AVC 有更大和更多的分區(qū)(和子分區(qū))選項(xiàng),更多幀內(nèi)預(yù)測(cè)方向,改進(jìn)的熵編碼等,所有這些改進(jìn)使得 H.265 比 H.264 的壓縮率提升 50%。
音頻處理 :經(jīng)過 采樣 量化 編碼 壓縮。這里就不做詳細(xì)贅述。
SDL(Simple DirectMedia Layer)作為免費(fèi)的跨平臺(tái)多媒體應(yīng)用編程接口,已經(jīng)被人們廣泛用于開發(fā)二維游戲,其優(yōu)秀的消息框架支持、文件支持和聲音支持都使得它能與微軟DirectX匹敵。
現(xiàn)在很多game游戲里面,都采用 SDL+OpenGL ES 的模式來繪制3D界面。 可以讓SDL使用OpenGL ES的函數(shù)接口來渲染3D。
SDL庫(kù)的作用說白了就是封裝了復(fù)雜的視音頻底層操作,簡(jiǎn)化了視音頻處理的難度。
SDL(Simple DirectMedia Layer)是一套開放源代碼的跨平臺(tái)多媒體開發(fā)庫(kù),使用C語(yǔ)言寫成。SDL提供了數(shù)種控制圖像、聲音、輸出入的函數(shù),讓開發(fā)者只要用相同或是相似的代碼就可以開發(fā)出跨多個(gè)平臺(tái)(Linux、Windows、Mac OS X等)的應(yīng)用軟件。目前SDL多用于開發(fā)游戲、模擬器、媒體播放器等多媒體應(yīng)用領(lǐng)域。
雖然SDL時(shí)常被比較為‘跨平臺(tái)的DirectX’,然而事實(shí)上SDL是定位成以精簡(jiǎn)的方式來完成基礎(chǔ)的功能,它大幅度簡(jiǎn)化了控制圖像、聲音、輸出入等工作所需撰寫的代碼。但更高級(jí)的繪圖功能或是音效功能則需搭配OpenGL和OpenAL等API來達(dá)成。另外它本身也沒有方便創(chuàng)建圖形用戶界面的函數(shù)。
SDL在結(jié)構(gòu)上是將不同操作系統(tǒng)的庫(kù)再包裝成相同的函數(shù),例如SDL在Windows平臺(tái)上其實(shí)是DirectX的再包裝,舊版本包裝的是DirectX 5,現(xiàn)時(shí)的版本(SDL 1.2)則是DirectX 7。而在使用X11的平臺(tái)上(包括Linux),SDL則是與Xlib庫(kù)溝通來輸出圖像。
雖然SDL本身是使用C語(yǔ)言寫成,但是它幾乎可以被所有的編程語(yǔ)言所使用,例如:C++、Perl、Python(借由pygame庫(kù))、Pascal等等,甚至是Euphoria、Pliant這類較不流行的編程語(yǔ)言也都可行。
SDL庫(kù)分為 Video、Audio、CD-ROM、Joystick 和 Timer 等若干子系統(tǒng),除此之外,還有一些單獨(dú)的官方擴(kuò)充函數(shù)庫(kù)。這些庫(kù)由官方網(wǎng)站提供,并包含在官方文檔中,共同組成了SDL的“標(biāo)準(zhǔn)庫(kù)”:
SDL_image—支持時(shí)下流行的圖像格式:BMP、PPM、XPM、 PCX、GIF、JPEG、PNG、TGA。
SDL_mixer—更多的聲音輸出函數(shù)以及更多的聲音格式支持。
SDL_net—網(wǎng)絡(luò)支持。
SDL_ttf—TrueType字體渲染支持。
SDL_rtf—簡(jiǎn)單的RTF渲染支持。
子系統(tǒng)
SDL將功能分成下列數(shù)個(gè)子系統(tǒng)(subsystem):
Video(圖像)—圖像控制以及線程(thread)和事件管理(event)。
Audio(聲音)—聲音控制
Joystick(搖桿)—游戲搖桿控制
CD-ROM(光盤驅(qū)動(dòng)器)—光盤媒體控制
Window Management(視窗管理)-與視窗程序設(shè)計(jì)集成
Event(事件驅(qū)動(dòng))-處理事件驅(qū)動(dòng)
一.ffmpeg (ffmpeg命令 和 ffmpeg編程)
ffprobe用于探測(cè)媒體文件的格式以及詳細(xì)信息,ffplay是一個(gè)播放媒體文件的工具,那么ffmpeg就是強(qiáng)大的媒體文件轉(zhuǎn)換工具。它可以轉(zhuǎn)換任何格式的媒體文件,并且還可以用自己的AudioFilter以及VideoFilter進(jìn)行處理和編輯。ffmpeg是一套視頻處理和存儲(chǔ)等的技術(shù)方案,重點(diǎn)“開源”、“免費(fèi)”,“最主流的視頻處理技術(shù)方案”。
ffmpeg屬于GPL或者LGPL,確切屬于哪一種,要根據(jù)編譯選項(xiàng),因?yàn)樗锩娴膸?kù)有些屬于GPL的有些屬于LGPL的,你編譯的時(shí)候打開或者關(guān)閉這些庫(kù)的選項(xiàng),就決定了它屬于哪一種。
二、Xvid
Xvid(舊稱為XviD)是一個(gè)開放源代碼的MPEG-4視頻編解碼器,它是基于OpenDivX而編寫的。官方網(wǎng)站:www.xvid.org
三、X264
X264是一種免費(fèi)的、具有更優(yōu)秀算法的符合H.264/MPEG-4 AVC視頻壓縮編碼標(biāo)準(zhǔn)格式的編碼庫(kù)。x264壓縮出的視頻文件在相同質(zhì)量下要比xvid壓縮出的文件要小,或者也可以說,在相同體積下比xvid壓縮出的文件質(zhì)量要好。它符合GPL(General Public License,是一份GNU通用公共授權(quán))許可證。X264屬于videolan開源工程的一部分。
采用CAVLC/CABAC多種算法編碼
內(nèi)置所有macroblock格式(16x16, 8x8, and 4x4 )
Inter P:所有的分割塊(從16x16到4x4 )
Inter B:分割塊從16x16到8x8
碼率控制:恒定的分層編制,單次或多次的ABR壓制,可選的VBV壓制
場(chǎng)景剪切偵測(cè)
支持B-frame
能夠任意編制B-frame命令行
無損模式
8x8和4x4的格式能夠進(jìn)行翻轉(zhuǎn)或旋轉(zhuǎn)
自定義精確的矩陣模板
可在多個(gè)CPU平行編碼
隔行掃描
X264只提供編碼,不提供解碼。 解碼部分需要FFMPEG完成;XVID有編解碼部分,其中解碼亦可以利用FFMPEG中的MPEG4完成解碼。
四、ffdshow
ffdshow是對(duì)一些codec(ffmpeg, xvid, and other)的封裝,封裝成了DirectShow和VFW的標(biāo)準(zhǔn)組件。該庫(kù)(軟件)只能在windows平臺(tái)運(yùn)行,是屬于GPL
比如對(duì)于xvid來講,ffdshow是可以選擇具體使用那個(gè)codec的,ffmpeg(libavcodec) or xvid。那么封裝有沒有額外的成本哪?有,但對(duì)大部分應(yīng)用來講,可以忽略不計(jì)。就如c++和c。
vfw和dshow里的CODEC分別是通過fourcc碼和guid機(jī)制尋找的,可以在系統(tǒng)注冊(cè)codec后調(diào)用,比自帶編解碼庫(kù)形式更加統(tǒng)一,便于使用。此外,vfw和dshow是代表了兩個(gè)微軟不同時(shí)期的音視頻處理封裝庫(kù),里面包含了音視頻驅(qū)動(dòng),音視頻處理的一整套方案。
DirectShow是微軟公司在ActiveMovie和Video for Windows的基礎(chǔ)上推出的新一代基于COM的流媒體處理的開發(fā)包,與DirectX開發(fā)包一起發(fā)布。目前,DirectX最新版本為9.0。 DirectShow為多媒體流的捕捉和回放提供了強(qiáng)有力的支持。運(yùn)用DirectShow,我們可以很方便地從支持WDM驅(qū)動(dòng)模型的采集卡上捕獲數(shù)據(jù), 并且進(jìn)行相應(yīng)的后期處理乃至存儲(chǔ)到文件中。這樣使在多媒體數(shù)據(jù)庫(kù)管理系統(tǒng)(MDBMS)中多媒體數(shù)據(jù)的存取變得更加方便。DirectShow是微軟公司 提供的一套在Windows平臺(tái)上進(jìn)行流媒體處理的開發(fā)包,與DirectX開發(fā)包一起發(fā)布。運(yùn)用DirectShow,我們可以很方便地從支持WDM驅(qū)動(dòng)模型的采集卡上捕獲數(shù)據(jù),并且進(jìn)行相應(yīng)的后期處理乃至存儲(chǔ)到文件中。它廣泛地支持各種媒體格 式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒體數(shù)據(jù)的回放變得輕而易舉。另外,DirectShow還集成了DirectX 其它部分(比如DirectDraw、DirectSound)的技術(shù),直接支持DVD的播放,視頻的非線性編輯,以及與數(shù)字?jǐn)z像機(jī)的數(shù)據(jù)交換。
五、CoreAVC
CoreCodec的CoreAVC高清H.264視頻解碼器是基于已經(jīng)被用于AVCHD、藍(lán)光光盤和HD-DVD中的MPEG-4 Part 10標(biāo)準(zhǔn)構(gòu)建的。H.264是下一代的視頻編碼標(biāo)準(zhǔn),而CoreAVC?是目前公認(rèn)世界上最快的H.264軟解碼器。
簡(jiǎn)單介紹一下 Libyuv庫(kù)是一個(gè)專門對(duì)YUV數(shù)據(jù)進(jìn)行轉(zhuǎn)換縮放旋轉(zhuǎn)的庫(kù)
YUV是Google已經(jīng)開源了專門用于YUV數(shù)據(jù)的處理的庫(kù)。它擁有如下特性
1、libYUV是一個(gè)開源的實(shí)現(xiàn)各種YUV,RGB色彩之間的轉(zhuǎn)換、旋轉(zhuǎn)、縮放
2、支持windows、linux系統(tǒng),支持x86、arm架構(gòu)
3、支持SSE、AVX、NEON加速,在編譯時(shí)會(huì)根據(jù)硬件平臺(tái)旋轉(zhuǎn)使用的實(shí)現(xiàn)方式
在日常開發(fā)中,特別是在編解碼的項(xiàng)目中,數(shù)據(jù)格式轉(zhuǎn)換是很常見的,如YUV轉(zhuǎn)RGB、YU12轉(zhuǎn)I420、亦或者其他格式等等,我們常用的轉(zhuǎn)換方式,要么使用Opencv的cvtColor(),要么使用FFmepg的sws_scale(),單幀圖片進(jìn)行轉(zhuǎn)換還好,但如果我們?cè)谝曨l處理過程中使用,就會(huì)發(fā)現(xiàn)數(shù)據(jù)延遲,內(nèi)存增長(zhǎng)等各種問題,常見的處理方式是丟幀。
視頻傳輸協(xié)議詳解(RTMP、RTSP、HLS)
RTMP——Real Time Messaging Protocol(實(shí)時(shí)消息傳輸協(xié)議)
RTMP是由Adobe公司提出的,在互聯(lián)網(wǎng)TCP/IP五層體系結(jié)構(gòu)中應(yīng)用層,RTMP協(xié)議是基于TCP協(xié)議的,也就是說RTMP實(shí)際上是使用TCP作為傳輸協(xié)議。TCP協(xié)議在處在傳輸層,是面向連接的協(xié)議,能夠?yàn)閿?shù)據(jù)的傳輸提供可靠保障,因此數(shù)據(jù)在網(wǎng)絡(luò)上傳輸不會(huì)出現(xiàn)丟包的情況。不過這種可靠的保障也會(huì)造成一些問題,也就是說前面的數(shù)據(jù)包沒有交付到目的地,后面的數(shù)據(jù)也無法進(jìn)行傳輸。幸運(yùn)的是,目前的網(wǎng)絡(luò)帶寬基本上可以滿足RTMP協(xié)議傳輸普通質(zhì)量視頻的要求。
RTMP在TCP通道上一般傳輸?shù)氖莊lv 格式流
RTMP 握手分為簡(jiǎn)單握手和復(fù)雜握手,現(xiàn)在Adobe公司使用RTMP協(xié)議的產(chǎn)品應(yīng)該用的都是復(fù)雜握手,這里不介紹,只說簡(jiǎn)單握手。 按照網(wǎng)上的說法RTMP握手的過程如下
1.握手開始于客戶端發(fā)送C0、C1塊。服務(wù)器收到C0或C1后發(fā)送S0和S1。
1.當(dāng)客戶端收齊S0和S1后,開始發(fā)送C2。當(dāng)服務(wù)器收齊C0和C1后,開始發(fā)送S2。
2.當(dāng)客戶端和服務(wù)器分別收到S2和C2后,握手完成。
在實(shí)際工程應(yīng)用中,一般是客戶端先將C0, C1塊同時(shí)發(fā)出,服務(wù)器在收到C1 之后同時(shí)將S0, S1, S2發(fā)給客戶端。S2的內(nèi)容就是收到的C1塊的內(nèi)容。之后客戶端收到S1塊,并原樣返回給服務(wù)器,簡(jiǎn)單握手完成。按照RTMP協(xié)議個(gè)要求,客戶端需要校驗(yàn)C1塊的內(nèi)容和S2塊的內(nèi)容是否相同,相同的話才徹底完成握手過程,實(shí)際編寫程序用一般都不去做校驗(yàn)。
RTMP握手的這個(gè)過程就是完成了兩件事:1. 校驗(yàn)客戶端和服務(wù)器端RTMP協(xié)議版本號(hào),2. 是發(fā)了一堆數(shù)據(jù),猜想應(yīng)該是測(cè)試一下網(wǎng)絡(luò)狀況,看看有沒有傳錯(cuò)或者不能傳的情況。
2. RTMP 分塊
創(chuàng)建RTMP連接算是比較難的地方,開始涉及消息分塊(chunking)和 AFM(也是Adobe家的東西)格式數(shù)據(jù)的一些東西。
RTMP傳輸?shù)臄?shù)據(jù)的基本單元為Message,但是實(shí)際上傳輸?shù)淖钚卧荂hunk(消息塊),因?yàn)镽TMP協(xié)議為了提升傳輸速度,在傳輸數(shù)據(jù)的時(shí)候,會(huì)把Message拆分開來,形成更小的塊,這些塊就是Chunk。
Message結(jié)構(gòu)分析
1.Message Type:它是一個(gè)消息類型的ID,通過該ID接收方可以判斷接收到的數(shù)據(jù)的類型,從而做相應(yīng)的處理。Message Type ID在1-7的消息用于協(xié)議控制,這些消息一般是RTMP協(xié)議自身管理要使用的消息,用戶一般情況下無需操作其中的數(shù)據(jù)。Message Type ID為8,9的消息分別用于傳輸音頻和視頻數(shù)據(jù)。Message Type ID為15-20的消息用于發(fā)送AMF編碼的命令,負(fù)責(zé)用戶與服務(wù)器之間的交互,比如播放,暫停等。
2.Playload Length: 消息負(fù)載的長(zhǎng)度,即音視頻相關(guān)信息的的數(shù)據(jù)長(zhǎng)度,4個(gè)字節(jié)
3.TimeStamp:時(shí)間戳,3個(gè)字節(jié)。
4.Stream ID:消息的唯一標(biāo)識(shí)。拆分消息成Chunk時(shí)添加該ID,從而在還原時(shí)根據(jù)該ID識(shí)別Chunk屬于哪個(gè)消息。
5.Message Body:消息體,承載了音視頻等信息。
消息塊(Chunk)
消息塊結(jié)構(gòu)
通過上圖可以看出,消息塊在結(jié)構(gòu)上與與消息類似,有Header和Body。
1.Basic Header:基本的頭部信息,在頭部信息里面包含了chunk stream ID(流通道Id,用來標(biāo)識(shí)指定的通道)和chunk type(chunk的類型)。
2.Message Header:消息的頭部信息,包含了要發(fā)送的實(shí)際信息(可能是完整的,也可能是一部分)的描述信息。Message Header的格式和長(zhǎng)度取決于Basic Header的chunk type。
3.Extended TimeStamp:擴(kuò)展時(shí)間戳。
4.Chunk Data:塊數(shù)據(jù)。
RTMP在傳輸數(shù)據(jù)的時(shí)候,發(fā)送端會(huì)把需要傳輸?shù)拿襟w數(shù)據(jù)封裝成消息,然后把消息拆分成消息塊,再一個(gè)一個(gè)進(jìn)行傳輸。接收端收到消息塊后,根據(jù)Message Stream ID重新將消息塊進(jìn)行組裝、組合成消息,再解除該消息的封裝處理就可以還原出媒體數(shù)據(jù)。由此可以看出,RTMP收發(fā)數(shù)據(jù)是以Chunk為單位,而不是以Message為單位。需要注意的是,RTMP發(fā)送Chunk必須是一個(gè)一個(gè)發(fā)送,后面的Chunk必須等前面的Chunk發(fā)送完成。
WebRTC
WebRTC,名稱源自網(wǎng)頁(yè)即時(shí)通信(英語(yǔ):Web Real-Time Communication)的縮寫,是一個(gè)支持網(wǎng)頁(yè)瀏覽器進(jìn)行實(shí)時(shí)語(yǔ)音對(duì)話或視頻對(duì)話的API。它于2011年6月1日開源并在Google、Mozilla、Opera支持下被納入萬(wàn)維網(wǎng)聯(lián)盟的W3C推薦標(biāo)準(zhǔn)
為什么要使用轉(zhuǎn)I420
1.Camera預(yù)覽格式:NV21、YV12 ,默認(rèn)是NV21 格式
2.H264編碼必須要用 I420格式的YUV420
YUV420的幾種格式
NV12,NV21,YV12,I420都屬于YUV420,但是YUV420 又分為YUV420P,YUV420SP,P與SP區(qū)別就是,前者YUV420P UV順序存儲(chǔ),而YUV420SP則是UV交錯(cuò)存儲(chǔ),這是最大的區(qū)別,具體的yuv排序就是這樣的:
I420: YYYYYYYY UU VV ->YUV420P
YV12: YYYYYYYY VV UU ->YUV420P
NV12: YYYYYYYY UVUV ->YUV420SP
NV21: YYYYYYYY VUVU ->YUV420SP
RTSP
RTSP(Real Time Streaming Protocol)是TCP/UDP協(xié)議體系中的一個(gè)應(yīng)用層協(xié)議,由哥倫比亞大學(xué), 網(wǎng)景和RealNetworks公司提交的IETF RFC標(biāo)準(zhǔn).該協(xié)議定義了一對(duì)多應(yīng)用程序如何有效地通過IP網(wǎng)絡(luò)傳輸多媒體數(shù)據(jù)。RTSP在體系結(jié)構(gòu)上位于RTP和RTCP之上,它使用TCP或者RTP完成數(shù)據(jù)傳輸,目前市場(chǎng)上大多數(shù)采用RTP來傳輸媒體數(shù)據(jù)。
一次基本的RTSP操作過程:
首先,客戶端連接到流服務(wù)器并發(fā)送一個(gè)RTSP描述命令(DESCRIBE)。
流服務(wù)器通過一個(gè)SDP描述來進(jìn)行反饋,反饋信息包括流數(shù)量、媒體類型等信息。
客戶端再分析該SDP描述,并為會(huì)話中的每一個(gè)流發(fā)送一個(gè)RTSP建立命令(SETUP),RTSP建立命令告訴服務(wù)器客戶端用于接收媒體數(shù)據(jù)的端口。流媒體連接建立完成后,
客戶端發(fā)送一個(gè)播放命令(PLAY),服務(wù)器就開始在UDP上傳送媒體流(RTP包)到客戶端。 在播放過程中客戶端還可以向服務(wù)器發(fā)送命令來控制快進(jìn)、快退和暫停等。
最后,客戶端可發(fā)送一個(gè)終止命令(TERADOWN)來結(jié)束流媒體會(huì)話。
由上圖可以看出,RTSP處于應(yīng)用層,而RTP/RTCP處于傳輸層。RTSP負(fù)責(zé)建立以及控制會(huì)話,RTP負(fù)責(zé)多媒體數(shù)據(jù)的傳輸。而RTCP是一個(gè)實(shí)時(shí)傳輸控制協(xié)議,配合RTP做控制和流量監(jiān)控。封裝發(fā)送端及接收端(主要)的統(tǒng)計(jì)報(bào)表。這些信息包括丟包率,接收抖動(dòng)等信息。發(fā)送端根據(jù)接收端的反饋信息做響應(yīng)的處理。RTP與RTCP相結(jié)合雖然保證了實(shí)時(shí)數(shù)據(jù)的傳輸,但也有自己的缺點(diǎn)。最顯著的是當(dāng)有許多用戶一起加入會(huì)話進(jìn)程的時(shí)候,由于每個(gè)參與者都周期發(fā)送RTCP信息包,導(dǎo)致RTCP包泛濫(flooding)。
簡(jiǎn)單的RTSP消息交互過程
C表示RTSP客戶端,S表示RTSP服務(wù)端
第一步:查詢服務(wù)器端可用方法
C->S OPTION request //詢問S有哪些方法可用
S->C OPTION response //S回應(yīng)信息的public頭字段中包括提供的所有可用方法
第二步:得到媒體描述信息
C->S DESCRIBE request //要求得到S提供的媒體描述信息
S->C DESCRIBE response //S回應(yīng)媒體描述信息,一般是sdp信息
第三步:建立RTSP會(huì)話
C->S SETUP request //通過Transport頭字段列出可接受的傳輸選項(xiàng),請(qǐng)求S建立會(huì)話
S->C SETUP response //S建立會(huì)話,通過Transport頭字段返回選擇的具體轉(zhuǎn)輸選項(xiàng),并返回建立的Session ID;
第四步:請(qǐng)求開始傳送數(shù)據(jù)
C->S PLAY request //C請(qǐng)求S開始發(fā)送數(shù)據(jù)
S->C PLAY response //S回應(yīng)該請(qǐng)求的信息
第五步: 數(shù)據(jù)傳送播放中
S->C 發(fā)送流媒體數(shù)據(jù) // 通過RTP協(xié)議傳送數(shù)據(jù)
第六步:關(guān)閉會(huì)話,退出
C->S EARDOWN request //C請(qǐng)求關(guān)閉會(huì)話
S->C TEARDOWN response //S回應(yīng)該請(qǐng)求
上述的過程只是標(biāo)準(zhǔn)的、友好的rtsp流程,但實(shí)際的需求中并不一定按此過程。 其中第三和第四步是必需的!第一步,只要服務(wù)器和客戶端約定好有哪些方法可用,則option請(qǐng)求可以不要。第二步,如果我們有其他途徑得到媒體初始化描述信息(比如http請(qǐng)求等等),則我們也不需要通過rtsp中的describe請(qǐng)求來完成。
HLS —— HTTP Live Streaming
HTTP Live Streaming(縮寫是HLS)是一個(gè)由蘋果公司提出的基于Http協(xié)議的的流媒體網(wǎng)絡(luò)傳輸協(xié)議。是蘋果公司QuickTime X和iPhone軟件系統(tǒng)的一部分。它的工作原理是把整個(gè)流分成一個(gè)個(gè)小的基于HTTP的文件來下載,每次只下載一些。當(dāng)媒體流正在播放時(shí),客戶端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會(huì)話適應(yīng)不同的數(shù)據(jù)速率。在開始一個(gè)流媒體會(huì)話時(shí),客戶端會(huì)下載一個(gè)包含元數(shù)據(jù)的extended M3U (m3u8)playlist文件,用于尋找可用的媒體流。
HLS協(xié)議的優(yōu)點(diǎn):
1.跨平臺(tái)性:支持iOS/Android/瀏覽器,通用性強(qiáng)。
2.穿墻能力強(qiáng):由于HLS是基于HTTP協(xié)議的,因此HTTP數(shù)據(jù)能夠穿透的防火墻或者代理服務(wù)器HLS都可以做到,基本不會(huì)遇到被防火墻屏蔽的情況。
3.切換碼率快(清晰度):自帶多碼率自適應(yīng),客戶端可以選擇從許多不同的備用源中以不同的速率下載同樣的資源,允許流媒體會(huì)話適應(yīng)不同的數(shù)據(jù)速率??蛻舳丝梢院芸斓倪x擇和切換碼率,以適應(yīng)不同帶寬條件下的播放。
3.負(fù)載均衡:HLS基于無狀態(tài)協(xié)議(HTTP),客戶端只是按照順序使用下載存儲(chǔ)在服務(wù)器的普通TS文件,做負(fù)責(zé)均衡如同普通的HTTP文件服務(wù)器的負(fù)載均衡一樣簡(jiǎn)單。
HLS的缺點(diǎn):
1.實(shí)時(shí)性差:蘋果官方建議是請(qǐng)求到3個(gè)片之后才開始播放。所以一般很少用HLS做為互聯(lián)網(wǎng)直播的傳輸協(xié)議。假設(shè)列表里面的包含5個(gè) ts 文件,每個(gè) TS 文件包含5秒的視頻內(nèi)容,那么整體的延遲就是25秒。蘋果官方推薦的ts時(shí)長(zhǎng)時(shí)10s,所以這樣就會(huì)大改有30s(n x 10)的延遲。
2.文件碎片化嚴(yán)重:對(duì)于點(diǎn)播服務(wù)來說, 由于 TS 切片通常較小, 海量碎片在文件分發(fā), 一致性緩存, 存儲(chǔ)等方面都有較大挑戰(zhàn).
總結(jié)
- 上一篇: 硬件知识:SSD越用越慢的原因,看完你就
- 下一篇: APP技巧:盘点微信去年更新的9个更新功