1. 程式人生 > >srs之深入淺出看流媒體

srs之深入淺出看流媒體

本文轉載 CDN這幾年爆炸式增長,頻寬提速是根源,而HTTP始終還是那個屌樣,因此目前CDN大多是資本性行業,不用多少知識就能幹了;直到流媒體粗現,直播咋這麼難搞呢?因為它是流媒體,讓我帶你深入淺出看流媒體前世今生,分分鐘二逼變牛逼。流媒體分為點播和直播,點播已經墮落為HTTP檔案了,直播永遠不可能只用HTTP就OK,這是他們的業務差異導致的。流媒體本質上是:現實的影象,經過編碼器壓縮,持久化為點播檔案或者直播流,經過傳輸,在終端解碼和展示。點播為何屬於HTTP而不是流媒體呢?點播,譬如電影或者錄製的影像,傳輸給觀看的終端時是不變的,一萬個人看一個電影無論什麼時候看都是一樣的媒體資料,因此傳輸上直接使用HTTP就可以了。點播的流媒體特徵還是有的:
1.點播的重新編碼,譬如為不同終端輸出不同位元速率和尺寸的點播檔案,需要媒體知識了。這部分因為使用太廣泛,所以開源屆早就支援得很成熟,ffmpeg對檔案重新編碼已經做得很好了。2.點播P2P,這個實際上分為客戶端的P2P和web P2P,這個和媒體沒有什麼關係,但屬於點播需要做的範圍,沒有現成的方案。(插播廣告:觀止創想已經支援了點播HLS的P2P,現有系統不用修改就可以加上web P2P)3.其他的什麼分片,DRM,彈幕,分享,多終端轉封裝,檔案排程,HTTP API排程,熱點,mp4/flv-range請求,儲存等等。大多都有了成熟的方案,和HTTP檔案一樣的技術,要麼就是播放器支援,這些和流媒體一毛錢關係都沒有。
這就是為何CDN支援點播支援得很得心應手,幾乎所有的CDN都能直接支援點播分發,甚至一些新興的行業公司,譬如線上教育,對於點播都能自己搞。點播就是HTTP而已,不屬於流媒體範疇。直播呢,從古老的RTSP到RTMP,HTTP漸進式下載,到HTTP流,到HLS和HDS,到DASH,到私有的websocket。這些不過是直播分發的表象,譬如HTTP直播流就是HTTP點播嗎?不是。HTTP點播本質上是檔案分發,而HTTP流是流媒體伺服器在記憶體中將直播的包,打包成RTSP、RTMP、HTTP後傳送給每個客戶端。當然總有例外的,有一個公司嘗試過直播進行點播化,就是時移直播,將直播流錄製成點播檔案,然後客戶端請求時總是請求點播。這種私有協議遲早是要死掉的,只有自己的播放器能播,而且得在CDN上部署自己的流媒體;現在這個公司也放棄了自己的“高大上”的私有協議——網際網路的基本精神就是開放標準。可惜中國人很難認同這個理念,牛逼的總喜歡搞私有協議,譬如使用websocket的公司,大多屬於這種型別,牛逼的人太多就是這種結果,一般這種公司也很有錢,譬如某上市的做線上秀場的公司。
目前直播分發有幾個特點:1.偏好flv,少用ts:flv標準11頁,ts標準174頁。標準文件十倍差異,程式碼實現起來十倍都不止。因此一般的公司都喜歡flv,pc時代都是flv的天下,什麼flv流,flv切片;因為自己寫程式碼支援ts比較麻煩,用ffmpeg的程式碼又太龐大。直到移動端粗現,現在直播只支援pc的少之又少了,使用flv作為基礎結構的產品要麼艱難轉型,要麼就掩耳盜鈴說FLV很優雅,HLS太垃圾。2.rtmp和hls並存:rtmp一般用於pc-flash播放直播,而hls用於移動端播放。flash能播放hls嗎?前年jwplayer就支援了,可惜是商業版不開源;去年有很多開源的as播放器支援hls。而直播系統,特別是cdn的直播,不會更新這麼快,pc端還是rtmp係為主。這個特點是由於平臺客戶端支援的流決定的,並非最佳方案,也不是使用者願意這麼幹。3.實時流大多使用rtmp:實時流,延遲要求在5秒之內的流,大多使用rtmp協議。pc上可以直接播放,移動端就需要使用ffmpeg解碼播放。有沒有更好的分發方案?實際上http-flv比rtmp更合適,延遲一樣,要求伺服器支援,pc能直接播,移動端需要使用ffmpeg,還有個好處是能穿牆。為何cdn大多不支援http-flv直播?因為一般的web伺服器支援不了,這是個流媒體問題。4.rtsp永遠死不了:這是監控行業的協議,我們都有門戶之見,“RTMP這個爛貨怎麼還在網際網路上用呢?RTSP多麼優美!”因此有監控行業背景的公司做網際網路業務,都帶著門戶之見不得已將RTSP轉RTMP,而且還要憤憤的說——只不過是不用裝個外掛而已。直播的本質特點,就是需要專門的伺服器分發,至少需要直播源站切片HLS後分發。也就是直播需要專門的流媒體伺服器,目前開源的流媒體,最古老的是RED5,後面是CRTMPD,風生水起的是NGINX-RTMP,目前最新出的是SRS(Simple Rtmp Server)。為何RED5不能一統天下?RED5和FMS一樣古老,先行者如果不能放掉自己的光環,遲遲不肯變革,就會被後來者超越。RED5效能是很差,但並非是因為使用了java的原因,這個看看wowza就知道了,商業伺服器wowza雖然是個記憶體殺手,但是支援的併發一點都不含糊。RED5沒有廣泛商用的原因可能一直是一個先行者,祖先的角色。軟體只有快速變化適應需求才能發展,和年紀沒有關係。那麼CRTMPD怎樣?牛逼!使用單程序單執行緒非同步socket,這是和nginx同時代的產物。CRTMFPD是有不少鐵桿粉絲的,以那個時代開始做直播業務的為主。CRTMDP生不逢時,遇到NGINX了,不少NGINX的粉絲是技術牛逼的人物,不然怎麼能看懂void*****呢?除了社群的差異之外,CRTMPD沒有支援HLS,倒是支援了RTSP,這就是典型的倒行逆施,網際網路上支援RTSP,大約只有CRTMPD能想到了。NGINX-RTMP風生水起有幾個很重要的因素。首先2012年開始CDN業務開始快速增長,隨之直播業務也需求暴漲,沒有特別滿意的流媒體伺服器;其次,NGINX在HTTP領域絕對是霸主,大家對於NGINX系的熟悉程度很高,便於維護;再次,直播點播使用一套伺服器,很有誘惑力,這可以算是“萬金油”效應,很多套伺服器搞得焦頭爛額,肯定一套伺服器能解決問題;最後,CDN是運維比技術牛逼的行業,運維的信心都是執行出來的,NGINX執行那麼良好,那麼NGINX-RTMP也肯定不錯。SRS(Simple Rtmp Sever)粗來了,並非石頭縫裡蹦粗來個SRS(Simple Rtmp Sever),SRS(Simple Rtmp Sever)其實誕生的歷史是:第一個版本實際上是參考NGINX,基本上和NGINX-RTMP同時間點做出來;第二版本是改用ST作為基礎結構,支援RTMP直播點播;第三版本是從CDN出來後重寫的,只支援直播。為何SRS(Simple Rtmp Sever)不使用NGINX那種基礎結構,這個和google為何開發golang的原因一樣。SRS(Simple Rtmp Sever)和NGINX-RTMP最重要的區別有兩點:其一,使用類似golang的伺服器架構;其二,流媒體業務驅動的產品管理,如果可以裝裝逼,SRS(Simple Rtmp Sever)是以流媒體業務為主的伺服器,而不是以分發協議為主的伺服器。什麼是以流媒體為主?流媒體系統的層次包括:網路層(socket或st)負責傳輸,協議層(rtmp或http)負責網路打包,封裝層(flv、ts、hls、hds、adts、annexb)負責編解碼資料的封裝,編碼層(h.264和aac)負責影象壓縮。流媒體伺服器的重點在於封裝層,譬如flv、ts、hls、hds、adts和annexb的解析和打包都是自己實現的程式碼,參考標準規範,支援完善的封裝轉換和解析。而網路層因為使用st簡化,使得協議層更簡單,錯誤的概率更低,這個和流媒體的關係就不大了。什麼是以業務為主?“跑起來”和“商用”是兩回事情,商用需要對於流媒體的業務有很好的支援:譬如vhost,這個是計費才有的概念,基於app的也能計費,結果就是要求使用者不能app重複,新增app需要聯絡運維,凡是新增app需要聯絡運維的cdn,肯定是NGINX-RTMP;譬如日誌,出現問題能將流媒體的整個鏈條的日誌都能找出來,從邊緣到回源連結,到上層節點的日誌,一直追溯到推流連線的日誌,每個日誌都是基於連線的;譬如rtmp+http-flv+hls,國內主要的直播業務都能支援,還有hds可以供那些想裝逼的客戶用;更多牛逼的業務功能就不囉嗦了。對於流媒體伺服器,除非能忘記HTTP伺服器,才能看清楚到底為何流媒體和HTTP沒有一毛錢關係,而流媒體在於團隊對於流媒體和伺服器的理解,而並非找到一個萬金油伺服器能塗抹掉客戶問題。直播這麼多協議,這多麼伺服器,當前直播重心在哪裡?該如何選擇合適的協議?只要問自己三個問題就可以了:1.延遲要求,是否要求低於5秒的延遲?如果是硬指標,就只能選擇RTMP或HTTP-FLV流。移動端需要自己編譯FFMPEG支援,無法直接播放。2.終端適配,是否要求支援PC和移動端(IOS和Android)?如果需要廣泛支援移動端,HLS是最好的選擇。3.節約頻寬,是否要求支援WebP2P?如果需要支援FlashP2P,或者移動端P2P,選擇HLS。當初有個跨國老牌的流媒體公司,勸說不要使用RTMP了,因為半年時間RTMP就會死掉,DASH會替代所有的流媒體協議。現在2年過去了,RTMP和HLS除了更加爆炸性應用之外,我看死掉的是那些過於技術至上的公司。如果用一句話說流媒體直播:實時性要求高的用RTMP或HTTP-FLV,其他都用HLS。協議請參考:https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DeliveryHLS伺服器請參考:https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Compare關於SRS(Simple Rtmp Sever)的架構參考:https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Architecture