RTSP 和 RTMP原理 通过ffmpeg实现将本地摄像头推流到RTSP服务器
RTSP 和 RTMP原理 & 通過ffmpeg實現將本地攝像頭推流到RTSP服務器
文章目錄
- RTSP 和 RTMP原理 & 通過ffmpeg實現將本地攝像頭推流到RTSP服務器
- 一、流媒體:RTSP 和 RTMP
- 0、參考資料
- 1、RTSP 和 RTMP的工作原理
- 1)RTSP工作原理
- 2)RTMP工作原理
- 2、RTSP 和 RTMP的優缺點
- 1)RTSP的優缺點
- 2)RTMP的優缺點
- 3)RTSP和RTMP的比較
- 3、RTSP和RTMP如何選擇
- 4、如何在瀏覽器上播放RTSP
- 二、ffmpeg將本地攝像頭推流到RTSP服務器
- 0、`ffmpeg`參考資料
- 1、安裝`ffmpeg`和`rtsp-simple-server`
- 1)windows安裝`rtsp-simple-server`和`ffmpeg`
- 2)linux安裝`rtsp-simple-server`和`ffmpeg`
- 2、將本地攝像頭推流到RTSP服務器
- 1)寫客戶端:ffmpeg
- 2)服務器端:RTSP服務器
- 3)讀客戶端:讀客戶端可以通過兩種方式來實現
- 3、存在問題:視頻讀取時延大
- 1)可能原因1:視頻編碼導致延遲高(親測效果不明顯)
- 2)可能原因2:設置`ffmpeg`參數(親測效果不明顯)
- 3)可能原因3:tcp連接導致延遲高
- 4)原因4:逐幀讀取時需要逐幀解碼,導致輸入和輸出速率不匹配導致延遲高(有效 - 抽幀讀取)
一、流媒體:RTSP 和 RTMP
0、參考資料
-
秒懂流媒體協議 RTMP 與 RTSP
-
什么是RTMP 和 RTSP?它們之間有什么區別?
-
RTSP和RTMP的區別是什么?
1、RTSP 和 RTMP的工作原理
1)RTSP工作原理
用戶設備向視頻流平臺發送 RTSP 請求
視頻流平臺返回可以操作的請求列表,比如播放、暫停等
用戶設備向視頻流平臺發送具體的請求,比如播放
視頻流平臺解析請求并調用指定機制啟動視頻流處理
由于 RTSP 依賴于專用服務器,并且依賴于 RTP(底層用到了UDP),因此該協議不支持加密視頻內容或重傳丟失的數據包。
這里解釋一下RTSP中是如何用到UDP和TCP的:
-
RTP協議,英文全稱:Real-time Transport Protocol,中文就是實時傳輸協議,它的底層其實就是UDP,這樣一來就可以實現低延遲。
-
除了RTP協議,為確保流暢和一致的流傳輸,RTSP 還使用另外兩種網絡通信協議:
- TCP 收發控制命令(例如播放或停止請求):TCP可靠傳輸,比如用戶按下播放或者停止播放的時候,這個是個準確的請求,這個需要保證可靠性,這個時候TCP作用就體現了。
- UDP傳送音頻、視頻和數據:UDP是低延遲的協議,那么用于傳送音頻、視頻和數據可以達到非常高效的效果。
這里可以通過開源的rtsp服務器可以簡單理解:TCP監聽端口為8554,UDP監聽端口為8000
2)RTMP工作原理
攝像頭捕獲視頻
通過編碼器將視頻流傳輸到視頻平臺服務器
視頻平臺處理視頻流
通過CDN分發到離用戶最近的服務器上
最后視頻流就能成功的到達用戶設備
在視頻從攝像頭到服務器的過程中,RTMP將大量數據分割成小塊并跨多個虛擬通道傳輸(內容分發網絡CDN),在視頻源和 RTMP 服務器之間提供了穩定和流暢的視頻流。
2、RTSP 和 RTMP的優缺點
1)RTSP的優缺點
-
RTSP的優點:
1、輕松自定義流:可以通過結合不同的協議來開發自己的視頻流解決方案。
2、分段流式傳輸:RTSP 流使觀看者能夠在下載完成之前訪問的視頻內容,而不必下載完整的視頻以流式傳輸內容。
-
RTSP的缺點:
1、與 HTTP不兼容:沒有簡單的解決方案可以在 Web 瀏覽器中播放 RTSP流,因為 RTSP 旨在通過私有網絡流式傳輸視頻,必須借用額外軟件。
2、使用率低:由于視頻播放器和流媒體服務并未廣泛支持 RTSP 流媒體,因為使用率比較低。
2)RTMP的優缺點
-
RTMP的優點:
1、低延遲:RTMP使用獨占的 1935 端口,無需緩沖,可以實現低延遲。
2、適應性強:所有 RTMP 服務器都可以錄制直播媒體流,同時還允許觀眾跳過部分廣播并在直播開始后加入直播流。
3、靈活性:RTMP 支持整合文本、視頻和音頻,支持 MP3 和 AAC 音頻流,也支持MP4、FLV 和 F4V 視頻。
-
RTMP的缺點:
1、HTML5 不支持:標準HTML5 播放器不支持 RTMP 流。
2、容易受到帶寬問題的影響:RTMP 流經常會出現低帶寬問題,造成視頻中斷。
3、HTTP 不兼容:無法通過 HTTP 流式傳輸 RTMP,必須需要實現一個特殊的服務器,并使用第三方內容交付網絡或使用流媒體視頻平臺。
3)RTSP和RTMP的比較
RTMP 和 RTSP協議 都是流媒體協議:
- RTMP(Real Time Message Protocol 實時消息傳遞協議) 有 Adobe 公司提出,用來解決多媒體數據傳輸流的多路復用(Multiplexing)和分包(packetizing)的問題,優勢在于低延遲,穩定性高,支持所有攝像頭格式,瀏覽器加載 flash插件就可以直接播放。
- RTSP (Real-Time Stream Protocol 實時流協議)由Real Networks 和 Netscape共同提出的,基于文本的多媒體播放控制協議。RTSP定義流格式,流數據經由RTP傳輸;RTSP實時效果非常好,適合視頻聊天,視頻監控等方向。
RTMP 和 RTSP協議 的區別:
-
RTSP雖然實時性最好,但是實現復雜,適合視頻聊天和視頻監控;
-
RTMP強在瀏覽器支持好,加載flash插件后就能直接播放,所以非常火,相反在瀏覽器里播放rtsp就很困難了。
3、RTSP和RTMP如何選擇
-
IP 攝像機選擇RTSP:幾乎所有 IP 攝像機都支持 RTSP,這是因為 IP 攝像機早在 RTMP 協議創建之前就已經存在,與 RTSP 和 IP 攝像機結合使用時,IP 攝像機本身充當 RTSP 服務器,這意味著要將攝像機連接到 IP 攝像機服務器并廣播視頻。
-
物聯網設備選擇RTSP:RTSP 通常內置在無人機或物聯網軟件中,從而可以訪問視頻源,它的好處之一是低延遲,確保視頻中沒有延遲,這對于無人機來說至關重要。
-
流媒體應用程序選擇RTMP:比如各種短視頻軟件、視頻直播軟件等都內置了RTMP,RTMP 是為滿足現代流媒體需求而設計的。
4、如何在瀏覽器上播放RTSP
-
直播的協議有:rtmp, http, rtsp等等。最常用的有二種:http, rtmp,當使用http協議的時候視頻格式需要是m3u8或flv,下面作詳細說明各種環境的優缺點。首先,rtsp不能使用于網頁環境(包含PC端和移動端),那么直播只能選擇rtmp或http。
-
rtmp協議只支持flashplayer,也就是只能在PC端(或安卓環境中安裝了flashplayer組件,這種環境比較少)安裝了flashplayer的情況下使用。按現在的趨勢,flashplayer是要逐漸被淘汰掉的。當然,在中國還會存在相對長時間。
-
http協議的直播分二種格式,m3u8和flv。flv是一種即將被淘汰的直播格式。用來做直播已顯的力不從心了。所以綜合考慮,m3u8相對的比較好點,優點是支持移動端,并且支持PC端上安裝了flashplayer的環境。缺點就如同rtmp一樣。flashplayer并不是未來的發展趨勢。另外一個缺點就是m3u8是有延遲的。并不能實時,實時傳輸方面不如rtmp協議。因為 m3u8的直播原理是將直播源不停的壓縮成指定時長的ts文件(比如9秒,10秒一個ts文件)并同時實時更新m3u8文件里的列表以達到直播的效果。這樣就會有一個至少9,10秒的時間延遲。如果壓縮的過小,可能導致客戶端網絡原因致視頻變卡。
實現rtsp轉http并使用m3u8格式進行直播 可以參考RTSP Webcam to HLS Live Streaming using FFMPEG and XAMPP | PART 1
具體過程:外接支持rtsp的webcam;使用ffplay命令來播放rtsp流,可以根據參數將實時視頻寫入到指定文件夾中(分段寫入);xampp開啟apache(開啟80端口),可以讓頁面通過保存的m3u8文件實時訪問webcam的監控界面。
二、ffmpeg將本地攝像頭推流到RTSP服務器
0、ffmpeg參考資料
- FFmpeg Protocols Documentation
- FFmpeg中文文檔
- FFmpeg流媒體處理-收流與推流
- FFmpeg發送流媒體的命令(UDP,RTP,RTMP)
- ffmpeg將本地攝像頭推流到RTSP服務器
- ffmpeg–使用命令+EasyDarwin推流筆記本攝像頭
- windows環境下,搭建RTSP視頻推流服務器
- windows環境下python使用ffmpeg rtsp推流
- 一個RtspServer的設計與實現和RTSP2.0簡介
- RTSP Webcam to HLS Live Streaming using FFMPEG and XAMPP | PART 1
Note:ffmpeg將本地攝像頭推流到rtsp的8554端口上(rtsp-simple-server在處理rtsp時,監聽的是8554端口,指定其他端口ffmpeg推流會失敗)
1、安裝ffmpeg和rtsp-simple-server
大致實現過程:使用rtsp-simple-server作為中轉服務器,用于ffmpeg(寫客戶端)推流,后臺服務(讀客戶端)拉流
1)windows安裝rtsp-simple-server和ffmpeg
參考windows環境下,搭建RTSP視頻推流服務器即可(記得修改rtsp-simple-server.yml配置文件中的ip地址)
2)linux安裝rtsp-simple-server和ffmpeg
-
安裝rtsp-simple-server_v0.20.2_linux_amd64.tar.gz(這里以x86 CPU為例),解壓后修改rtsp-simple-server.yml配置文件中的ip地址(vim替換命令為%s:/127.0.0.1/192.168.132.100/g),執行./rtsp-simple-server即可啟動rtsp服務器。
如果要想在后臺啟動rtsp服務器,執行如下命令
nohup ./rtsp-simple-server >> rtsp_server.log 2>&1 & #非掛起啟動命令tail rtsp_server.log #查看rtsp-simple-server啟動日志文件ps -aux | grep rtsp_simple_server #查看rtsp-simple-server進程 dpf 2116 0.0 0.0 13140 1016 pts/0 S+ 04:54 0:00 grep --color=auto rtsp_simple_server -
ffmpeg安裝地址如下https://johnvansickle.com/ffmpeg/,解壓后執行./ffmpeg即可使用ffmpeg,參考在linux下使用ffmpeg方法
Note:在linux中關于tar.gz,xz,tar的解壓操作請自行上網查閱。
2、將本地攝像頭推流到RTSP服務器
大致實現過程:使用rtsp-simple-server作為中轉服務器,用于ffmpeg(寫客戶端)推流,后臺服務(讀客戶端)拉流
這里以windows系統作為演示,先解壓rtsp-simple-server_v0.19.1_windows_amd64.zip,打開rtsp-simple-server.exe監聽RTSP下TCP的8554端口,然后通過ffmpeg將指定攝像頭采集到的圖像幀向該端口進行推流(即多個客戶端與服務器端的socket通信)
1)寫客戶端:ffmpeg
-
ffmpeg推流視頻文件到指定ip + 端口上(-stream_loop -1):
ffmpeg -re -stream_loop -1 -i 你視頻的文件名 -c copy -f rtsp rtsp://127.0.0.1:8554/videoFile_test -
ffmpeg將本地攝像頭的視頻流推送到指定ip + 端口上,則需要
//獲取本地攝像頭名稱 ffmpeg -list_devices true -f dshow -i dummy //ffmpeg向指定端口推流(我的是Integrated Camera) ffmpeg -f dshow -i video="自己的攝像頭驅動名稱" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/camera_test //libx264編碼 ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/camera_test
2)服務器端:RTSP服務器
-
初啟動效果如下:
-
開啟兩個ffmpeg模擬兩個寫客戶端,完成攝像頭采集視頻幀的推流和本地視頻文件的推流
該過程會出現兩個createby和publishing,在不同文件路徑下寫入圖像幀,可以通過指定進程(ip+端口)來處理(這里新創建了56725和56732兩個進程來處理),而RTSP的監聽端口仍然是8554,這樣可以實現非阻塞通信。
3)讀客戶端:讀客戶端可以通過兩種方式來實現
-
安裝VLC,選擇流數據播放模式,輸入rtsp://127.0.0.1:8554/camera_test,rtsp://127.0.0.1:8554/videoFile_test即可播放;
-
亦或者使用如下python代碼:
import cv2def capture_video(rtsp_path):name = rtsp_path.split("/")[-1]capture = cv2.VideoCapture(rtsp_path)while capture.isOpened():ret, frame = capture.read()if not ret:breakcv2.imshow(name, frame)if cv2.waitKey(50) == 27:breakif __name__ == '__main__':# rtsp_paths = ['rtsp://127.0.0.1:8554/videoFile_test','rtsp://127.0.0.1:8554/camera_test']rtsp_paths = ['rtsp://127.0.0.1:8554/videoFile_test']for rtsp_path in rtsp_paths:capture_video(rtsp_path)cv2.waitKey(0)cv2.destroyAllWindows()
此時會出現兩個createby和reading,即開啟兩個進程進行視頻流的讀取
3、存在問題:視頻讀取時延大
基于tcp和RTP的rtsp直播延遲很高,一開始延遲只有7s,由于TCP的擁塞控制,導致隨著時間推移,延遲越來越高,有14s之多。
1)可能原因1:視頻編碼導致延遲高(親測效果不明顯)
參考ffmpeg直播解決延時的關鍵方法,主要原因是使用libx264或者h264對視頻進行編碼的問題。
解決方法參考ffmpeg–使用命令+EasyDarwin推流筆記本攝像頭
//h264_qsv編碼(比libx264編碼快點) ffmpeg -f dshow -i video="Integrated Camera" -vcodec h264_qsv -tune:v zerolatency -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/camera_test //不使用編碼器,直接推送(但是很模糊) ffmpeg -f dshow -i video="Integrated Camera" -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/camera_test2)可能原因2:設置ffmpeg參數(親測效果不明顯)
參考解決ffmpeg的播放攝像頭的延時優化問題(項目案例使用有效) _
原參數:
-vcodec libx264, -r 25, -video_size 1280x720,優化參數1:
-tune zerolatency //設置零延時 -preset ultrafast //--preset的參數主要調節編碼速度和質量的平衡,有ultrafast(轉碼速度最快,視頻往往也最模糊)、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo這10個選項,從快到慢優化參數2:
-threads 4, -c:a copy, -fflags nobuffer, -max_delay 1, -vprofile baseline, -rtsp_transport tcp, -crf 30, -vsync 2, -f flvffmpeg完整命令如下:
ffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -r 25 -video_size 640x480 -tune:v zerolatency -preset:v ultrafast -threads 4 -c:a copy -fflags nobuffer -max_delay 1 -rtsp_transport tcp -crf 30 -vsync 2 -f flv -f rtsp rtsp://127.0.0.1:8554/camera_test3)可能原因3:tcp連接導致延遲高
參考RTSP end to end latency will be increasing when use tcp #902
ffmpeg在通過rtsp實現推流時默認是遵循tcp協議的,目的是為了保證消息可靠傳輸。對于實時音視頻通信,如果要想實現低延遲,要么增加帶寬,要么使用UDP進行傳輸。
4)原因4:逐幀讀取時需要逐幀解碼,導致輸入和輸出速率不匹配導致延遲高(有效 - 抽幀讀取)
解決方法:對于讀客戶端,采用抽幀讀取的方法來解決。如果采用逐幀讀取并完成解碼的方式,會讓寫客戶端不停地推流,而讀客戶端來不及解碼導致緩存區擁塞。
參考Opencv—視頻跳幀處理,OpenCV筆記:cv2.VideoCapture 完成視頻的跳幀輸出操作
ffmpeg寫客戶端命令無需修改:
//獲取本地攝像頭名稱 ffmpeg -list_devices true -f dshow -i dummyffmpeg -f dshow -i video="Integrated Camera" -vcodec libx264 -r 25 -video_size 640x480 -tune:v zerolatency -preset:v ultrafast -threads 4 -c:a copy -fflags nobuffer -max_delay 1 -rtsp_transport tcp -crf 30 -vsync 2 -f flv -f rtsp rtsp://127.0.0.1:8554/camera_testpython讀客戶端代碼修改如下:
def capture_video(rtsp_path):name = rtsp_path.split("/")[-1]capture = cv2.VideoCapture(rtsp_path) #不用帶cv2.CAP_DSHOWnow_fps = 0while capture.isOpened():# 設置每 10 幀輸出一次if (now_fps == 3):now_fps = 0ret, frame = capture.read()if not ret:breakcv2.imshow(name, frame)if cv2.waitKey(50) == 27:breakelse:# 跳幀,僅獲取幀但不做解碼處理ret = capture.grab()now_fps += 1總結
以上是生活随笔為你收集整理的RTSP 和 RTMP原理 通过ffmpeg实现将本地摄像头推流到RTSP服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奶茶妹妹章泽天加入微软Bing团队
- 下一篇: 当 IDENTITY_INSERT 设置