第一次寫博客,留個腳印先。
問題描述:
用支持html5的瀏覽器,不安裝插件,能夠播放rtsp協議的視頻。
可選技術路線:
1. nodejs + ffmpeg + jsmpeg
這個路線我沒有親測,有一個地方不太優雅,就是要調用ffmpeg進程進行視頻重編碼到mp1,有網友認爲不適合在生產環境下使用。
2. streamedian.js + streamedian server
streamedian 是開源的,自帶rtsp協議解析和h264視頻格式播放功能,在github上有, streamedian server 可以從www.streamedian.com網站上下載,免費版只支持本機播放,怎麼付費網站也沒寫。
3. 瀏覽器安裝vlc插件
vlc在chrome 41以上的版本用不了,屬於flash一類在網頁上面將被淘汰的東西,並且要求用戶都裝插件也不太方便。
搞了4天,最後我選了streamedian.js作爲前端,自己寫一個服務替換streamedian server。
方案構成:
streamedian.js + websocket server(主要嫁接websocket 與 rtsp通訊)
websocket server: 採用ASP.NET Core websocket庫,其中middleware架構學習了https://radu-matei.com/blog/aspnet-core-websockets-middleware/
rtsp通訊:由於streamedian.js自帶了rtsp報文解析,因此服務端主要是解析建立雙通道的RTSP報文,一個是INIT,一個是JION。INIT是控制報文使用的websocket鏈接,JOIN是數據報文(RTP)使用的websocket鏈接,兩者都關聯1個RTSP socket鏈接。
再就是當接受rtsp報文時需要根據報文內容分流爲數據報文和控制報文。
關於rtsp的客戶端代碼實現主要參考了github上的sharprtsp,但這個代碼性能實在不行。還有一個codeproject上的net7mma對視頻流解析實現的比較完善,但代碼過於複雜且沒什麼例子,對我這個方案借鑑意義不大。
代碼實現:
WebSocketMiddleware.cs 通用的websocket架構,複製過來的;
RtspProxy.cs 當收到報文時區分數據(以$字節開頭)、控制,分別入隊;
CameraWebSocketHandler.cs 主要處理websocket接受轉發給rtsp,以及rtsp隊列出隊轉發給websocket。
性能優化考慮:
1.socket讀取後不要直接轉發,入隊緩衝,以免堵塞rtsp流;
2.CameraWebSocketHandler 採用異步編程;
3.每次出隊多組報文,減少lock造成的性能損失。
代碼下載:https://download.csdn.net/download/xhydongda/10564021
TODO:
確保websocket鏈接資源正確關閉、釋放目前還不完善。