前段時間着手實現了一個RTSP Server,可以正常實現多路RTSP流的直播播放,因項目須要,只作了對H.264和AAC編碼的支持,可是相信其餘編碼的實現基本邏輯也是想通的。這裏我把主要設計和思考過程,以及實現框架分享一下。由於關注的是直播,這裏只討論RTSP直播協議。html
衆所周知,RTSP協議是一個流媒體協議,能夠實現直播和點播形式的音頻與視頻流的播放。RTSP協議定義了多種服務器-客戶端之間交互的接口,主要有OPTIONS,DESCRIBE,SETUP,PLAY,TEARDOWN,RECORD,ANNOUNCE。網絡上已經有不少針對RTSP協議的文章,我這裏不許備進行過多介紹,詳細的協議定義,能夠參見RFC2326。RTSP並不包括具體數據的傳輸,該功能通常由RTP與RTCP協議來實現,並能夠經過TCP或UDP兩種底層傳輸方式進行。
下圖是典型的RTSP直播過程當中服務端-客戶端主要交互過程:
固然,直播過程當中也可能在服務器與客戶端之間調用GET_PARAMETER等其餘接口,上圖偷懶省略了。上圖綠色部分表示的是數據傳輸。以前說過,流媒體數據傳輸不是RTSP協議的內容,由RTP包來作。可是具體在實現上,RTP包能夠經過UDP或TCP的方式來進行,並且這兩種傳輸方式,區別其實還不小,下面具體說下。服務器
對於udp模式,客戶端在發送PLAY之後,就開始創建udp端口,以接收服務器發來的RTP包,一樣,服務器也會創建udp端口,並向客戶端發送RTP包。這是網上大部分程序所採用的方式,優勢是邏輯清晰,實現方便,不過缺點也很明顯,就是udp所固有的,容易丟包,尤爲是在高分辨率高碼率下。
網絡
對tcp模式,經過SETUP接口來指定傳輸方式,服務器返回一樣數據以肯定雙方經過tcp方式來傳輸數據。不過跟udp最大的不一樣是,rtsp over tcp的形式,再也不建立單獨的tcp通道,而是直接使用以前rtsp通訊所使用的tcp通道,流程以下所示:
因爲跟rtsp消息使用同一個tcp端口,爲了區分,rtp以及rtcp包,增長了4個字節額外的字段,並經過特殊的標識'$',與正常的rtsp消息進行了區分。
框架
我此次所實現的RTSP Server,主要功能是採集攝像頭和麥克風數據,進行h.264編碼以及aac編碼,並對外提供RTSP直播流服務。我在實際寫代碼中,也是首先實現了rtsp over udp的模式,然而,經過實際測試,我發如今高分辨率高碼率狀況下,因爲h.264 NAL單元過大,會拆分紅不少的rtp包,而udp不可靠的傳輸方式,老是不免丟包,在低碼率的時候還不明顯,高碼率狀況下,丟包致使的花屏會頻繁出現,這樣體驗特別差。因而我從新實現了一份rtsp over tcp模式的代碼,順利解決了這個問題。
tcp
h264在sdp中的媒體信息,大多都是能夠直接填寫的,可是有兩項數據須要根據編碼後的數據來提取,就是profile-level-id和sprop-parameter-sets。這兩項字符串數據的計算公式
測試
3.1 Rtsp服務接口
3.2 RtspSession在TCP通道里處理RTSP消息與RTP報文
編碼
同時用vlc和ffplay進行多路播放,以tcp請求的方式,效果以下,延遲極低。
設計
2016年IETF發佈了新的RTSP標準,這就是就是RTSP2.0協議(RFC7826),新標準仍是有很多修改的,除了完善一些原協議的中的定義,還有一些我以爲比較重要的是,對接口method進行了修改,好比刪除了RECORD和ANNOUNCE方法,新增了PLAY_NOTIFY方法。
視頻
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++server
haibindev.cnblogs.com,合做請聯繫QQ。(轉載請註明做者和出處~)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++