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