Qt/C++開發監控GB28181系統/實時視頻預覽/視頻點播/rtp解包解碼顯示

一、前言

通過gb28181做實時視頻預覽,也就是視頻點播功能,是最重要的功能了,絕對是整個系統排第一重要的,這就是核心功能,什么設備注冊、獲取通道等都是為了實時預覽做準備的,當然這個功能也是最難的,所有搞gb28181開發的程序員,都是卡在這里很長一段時間才搞定,因為這個視頻點播的交互流程比較繞,很多人看到這個繞就心煩,心煩就沒辦法繼續寫下去,我也是靜下來心來很長一段時間才折騰好。對比onvif協議取流,不要太簡單,onvif直接獲取到的是rtsp視頻流地址,這個直接用ffmpeg或者vlc等就可以直接播放打開了,什么都不要自己交互。而gb這邊就要分很多步驟,就算最后一步完成后,拿到了傳過來的rtp包,有需要自己去解包,解包后再去發給ffmpeg等組件解碼才能最終呈現視頻,既有sip命令的交互,又是rtp包的解析,又是ps流轉成264265格式,最后才是解碼,意味著一旦斷開,相關的三種交互都需要做處理。

很多人一開始sip命令交互后,通過打開網絡調試助手,可以看到對應的數據包,然后就不知道下一步該如何搞了,我一開始也是以為這個包發給ffmpeg就能解碼,發現畫面完全不對,而且不動,查閱資料得知,原來這里的并不是ws或者flv這種就是264265的音視頻數據包,而是rtp包,需要重新解包才行。話說回來,為何不直接傳輸裸流數據?為了可以共用端口嗎?rtp包通過ssrc區分是哪一路流,感覺有點得不償失,還是希望后續能夠直接支持的就是裸流數據,這樣跳過解包這個步驟。

為了能夠簡化整個操作,專門封裝了一個gb28181widget窗體類,只需要調用openvideo就能打開預覽,closevideo就是關閉預覽,屏蔽了多個操作交互細節,比如打開視頻第一步是打開監聽端口,第二步把這個端口號信息告知設備,第三步應答ok準備好收流,第四步收到的流發給rtp線程解包,第五步解包后的數據發給ffmpeg解碼,第六步解碼后的數據發給qopenglwidget繪制。封裝了這個控件后,視頻回放那邊也可以直接復用這個,使用非常方便了。

//點播請求:服務端-》設備端
INVITE sip:34020000001310000001@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK4de987b1737d494d9c63bb1464c9cdcb
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1034
To: <sip:34020000001310000001@192.168.0.64:5060>
Call-ID: 445efb2b5134487788334cd6acafe0a2
CSeq: 35 INVITE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 323
Content-Type: application/sdp
Contact: <sip:34020000002000000001@192.168.0.110:15060>
Subject: 34020000001310000001:0000010000,34020000002000000001:0v=0
o=34020000001310000001 0 0 IN IP4 192.168.0.110
s=Play
u=34020000001310000001:0
c=IN IP4 192.168.0.110
t=0 0
m=video 8888 TCP/RTP/AVP 96 97 98
a=recvonly
a=setup:active
a=connection:new
a=rtpmap:96 PS/90000
a=rtpmap:97 MPEG4/90000
a=rtpmap:98 H264/90000
a=downloadspeed:0
a=streamprofile:0
y=0000010000//請求應答:設備端-》服務端
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK4de987b1737d494d9c63bb1464c9cdcb
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1034
To: <sip:34020000001310000001@192.168.0.64:5060>;tag=1561889054
Call-ID: 445efb2b5134487788334cd6acafe0a2
CSeq: 35 INVITE
Contact: <sip:34020000001320000002@192.168.0.64:5060>
Content-Type: application/sdp
User-Agent: IP Camera
Content-Length:   206v=0
o=34020000001320000002 2851 2851 IN IP4 192.168.0.64
s=Play
c=IN IP4 192.168.0.64
t=0 0
m=video 15060 TCP/RTP/AVP 96
a=setup:passive
a=sendonly
a=rtpmap:96 PS/90000
a=filesize:0
y=0000010000//開始點播:服務端-》設備端
ACK sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK4de987b1737d494d9c63bb1464c9cdcb
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1034
To: <sip:34020000001310000001@192.168.0.64:5060>;tag=1561889054
Call-ID: 445efb2b5134487788334cd6acafe0a2
CSeq: 35 ACK//結束點播:服務端-》設備端
BYE sip:34020000002000000001@192.168.0.110:15060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK7fe7407471734ba087eb4092db6ba108
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1019
To: <sip:34020000001310000001@192.168.0.100:5061>;tag=6d76ea76a4370853c9313f69995c7293
Call-ID: b5b5f90ba9b044868789d16fa3d0cc36
CSeq: 22 BYE
Contact: <sip:34020000002000000001@192.168.0.110:15060>

二、效果圖

在這里插入圖片描述

三、相關地址

  1. 國內站點:https://gitee.com/feiyangqingyun
  2. 國際站點:https://github.com/feiyangqingyun
  3. 個人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 文件地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取碼:01jf 文件名:bin_video_gb28181。

四、功能特點

  1. 支持設備注冊、注銷、心跳、校時、注冊認證、注銷認證等。
  2. 設備上線后可以手動獲取設備狀態、設備信息、配置信息、預置位信息等。
  3. 設備上線后自動獲取設備通道信息,包括中文通道名稱。識別到通道上線離線變化,會重新獲取該設備的所有通道信息。
  4. 支持視頻點播,可以分別點播主碼流和子碼流,內置rtp解包線程,解包后發給視頻播放組件解碼播放。
  5. 每個設備每個通道支持點播多個視頻,通過ssrc區分,支持共用端口和不同端口收流。
  6. 支持對某個設備下面所有通道、某個通道、某個通道對應的某個流分別關閉。
  7. 支持錄像文件查詢和回放,回放控制支持暫停播放、繼續播放、倍速播放、切換播放進度。
  8. 支持錄像文件下載,支持倍速比如8倍速下載,可同時多線程批量下載。
  9. 回放和下載同時支持IPC和NVR,比如攝像頭自帶的SD存儲卡錄像文件回放,NVR上的硬盤錄像文件回放。
  10. 支持云臺控制,向上、向下、向左、向右、左上、右上、左下、右下方位移動,鏡頭放大縮小,光圈放大縮小,鏡頭聚焦放焦。
  11. 支持預置位信息的查詢、調用、添加、修改、刪除等操作。
  12. 自動目錄訂閱功能,通道上線下線都有對應的信號通知。
  13. 內置定時讀取通道信息機制,以保證通道信息是最新的,比如有些NVR是不斷更新的通道信息。
  14. 內置訂閱警情和位置移動功能,訂閱后各種警情事件比如運動目標檢測報警、入侵檢測報警、徘徊檢測報警等自動上報。
  15. 支持語音對講功能,可以直接在視頻窗體的懸浮條上單擊語音對講按鈕,再次單擊關閉對講,對講期間懸浮條常駐顯示。
  16. 支持設備布防撤防,布防后警情信息會主動上報。
  17. 國標服務同時支持udp和tcp方式,可選只監聽一種或者兩種都監聽,tcp方式自動處理粘包問題。
  18. 國標拉流同時支持udp、tcp被動、tcp主動三種方式,每個通道都可以自由選擇何種拉流方式。
  19. 內置拉流端口池,每次拉流從中取出一個,關閉流自動回收端口號,重復利用。
  20. 收流端口自動糾錯,自動跳過被占用的端口,不會出現端口占用導致收流失敗的情況。
  21. 視頻播放自適應硬解碼,極低資源占用,實時性極好,帶懸浮條顯示視頻流信息,可以直接在懸浮條單擊按鈕保存錄像文件到本地。
  22. 支持幾千路國標消息交互并發,實時視頻流支持64路同時顯示,可以拓展更多路數。
  23. 支持阿里云等云服務器,可以分別設置內網監聽地址和外網訪問地址,一般云服務器上是監聽地址用內網,對外訪問用外網地址。
  24. 支持視頻分發,也就是推流,視頻通道打開后可以自動推流到流媒體服務器,其他需要的地方拉流即可,支持rtsp、rtmp、hls、webrtc等方式拉流。
  25. 同時支持gb28181-2011、gb28181-2016、gb28181-2022以及后續可能的所有協議版本。
  26. SIP解析和交互采用純Qt底層代碼實現,udp/tcp通信交互,祖傳原創代碼解析,不依賴任何第三方。
  27. 代碼量少,gb28181交互部分共幾千行代碼,注釋詳細,接口友好,使用極其簡單,提供非常詳細的使用示例。
  28. 支持海康、大華、宇視、華為、天地偉業等所有國標設備,包括一些沒有ssrc的設備。
  29. 支持所有Qt版本和編譯器以及操作系統,包括但不限于win、linux、mac、android、嵌入式linux、樹莓派香橙派、國產os等。

五、相關代碼

#include "rtphelper.h"
#include "rtpthreadreceive.h"RtpThreadReceive::RtpThreadReceive(QObject *parent) : RtpThreadBase(parent)
{}int RtpThreadReceive::getTimestamp()
{return 10;
}void RtpThreadReceive::run()
{this->stopped = false;RTPSession session;RTPAbortDescriptors descriptors;QTcpServer server;QTcpSocket socket;//根據不同的傳輸模式初始化bool ok = false;if (mode == 0) {ok = RtpHelper::initUdpServer(this, status, &session);} else if (mode == 1) {ok = RtpHelper::initTcpServer(this, status, &session, &descriptors, &server);} else if (mode == 2) {ok = RtpHelper::initTcpClient(this, status, &session, &descriptors, &socket);}//初始化失敗則不用繼續if (!ok) {emit receiveError(status);goto end;}//循環取出數據while (!stopped) {session.BeginDataAccess();if (session.GotoFirstSourceWithData()) {do {RTPPacket *packet;while ((packet = session.GetNextPacket()) != NULL) {pts = packet->GetTimestamp() / 9000;quint32 ssrc = session.GetCurrentSourceInfo()->GetSSRC();//qDebug() << TIMEMS << ssrc << packet->GetPayloadLength() << packet->GetSequenceNumber() << packet->HasMarker();QByteArray data((const char *)packet->GetPayloadData(), packet->GetPayloadLength());emit receiveData(data, ssrc);session.DeletePacket(packet);}} while (session.GotoNextSourceWithData());}session.EndDataAccess();msleep(1);}end:socket.disconnectFromHost();server.close();session.BYEDestroy(RTPTime(10, 0), 0, 0);this->free();
}bool RtpHelper::initUdpServer(RtpThreadBase *thread, int &status, RTPSession *session)
{QString host = thread->getServerIp();int port = thread->getServerPort();int timestamp = thread->getTimestamp();bool send = thread->inherits("RtpThreadSend");RTPSessionParams sessparams;sessparams.SetOwnTimestampUnit(1.0 / timestamp);//綁定要監聽的地址和端口RTPUDPv4TransmissionParams transparams;transparams.SetBindIP(QHostAddress(host).toIPv4Address());transparams.SetPortbase(port);//發送端還需要設置ssrcif (send) {sessparams.SetUsePredefinedSSRC(true);sessparams.SetPredefinedSSRC(1);}//循環監聽對應端口/直到監聽成功int max = 100;while (max > 0 && (status = session->Create(sessparams, &transparams)) < 0) {RtpHelper::debugErr(status, host, port);port = RtpHelper::takePort();transparams.SetPortbase(port);thread->sleepx(1);max--;}if (status < 0) {return false;}//通知外部打開成功qDebug() << TIMEMS << "bindUdpServer" << host << port;thread->openFinsh(port);//語音對講還需要設置發送端if (send) {if (!RtpHelper::initUdpClient(thread, status, session)) {return false;}} else {qDebug() << TIMEMS << "initUdpServer" << host << port;}return true;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80468.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

找銀子 題解(c++)

題目 思路 首先&#xff0c;這道題乍一看&#xff0c;應該可以用搜索來做。 但是&#xff0c;搜索會不會超時間限制呢&#xff1f; 為了防止時間超限,我們可以換一種做法。 先創立兩個二維數組&#xff0c;一個是輸入的數組a&#xff0c;一個是數組b。 假設 i 行 j 列的數…

子集樹算法文檔

1.算法概述 子集樹是一種 回溯算法&#xff0c;用于生成一個集合的所有子集。給定一個數組 arr&#xff0c;該算法遞歸地遍歷所有可能的子集&#xff0c;并通過一個輔助數組 x 標記當前元素是否被選中。 2.算法特點 時間復雜度&#xff1a;O(2n)&#xff08;因為一個包含 n 個…

HTTP/1.1 host虛擬主機詳解

一、核心需求&#xff1a;為什么需要虛擬主機&#xff1f; 在互聯網上&#xff0c;我們常常希望在一臺物理服務器&#xff08;它通常只有一個公網 IP 地址&#xff09;上運行多個獨立的網站&#xff0c;每個網站都有自己獨特的域名&#xff08;例如 www.a-site.com?, www.b-s…

amass:深入攻擊面映射和資產發現工具!全參數詳細教程!Kali Linux教程!

簡介 OWASP Amass 項目使用開源信息收集和主動偵察技術執行攻擊面網絡映射和外部資產發現。 此軟件包包含一個工具&#xff0c;可幫助信息安全專業人員使用開源信息收集和主動偵察技術執行攻擊面網絡映射并執行外部資產發現。 使用的信息收集技術 技術數據來源APIs&#xf…

Spring Web MVC響應

返回靜態頁面 第一步 創建html時&#xff0c;要注意創建的路徑&#xff0c;要在static下面 第二步 把需要寫的內容寫到body內 第三步 直接訪問路徑就可以 返回數據ResponseBody RestController Controller ResponseBody Controller&#xff1a;返回視圖 ResponseBody&…

?鴻蒙PC正式發布:國產操作系統實現全場景生態突破

鴻蒙PC正式發布&#xff1a;國產操作系統實現全場景生態突破? 2025年5月8日&#xff0c;華為在深圳舉辦發布會&#xff0c;正式推出搭載鴻蒙操作系統的個人電腦&#xff08;PC&#xff09;&#xff0c;標志著國產操作系統在核心技術與生態布局上實現歷史性跨越。此次發布的鴻蒙…

【計算機視覺】OpenCV實戰項目:Text-Extraction-Table-Image:基于OpenCV與OCR的表格圖像文本提取系統深度解析

Text-Extraction-Table-Image&#xff1a;基于OpenCV與OCR的表格圖像文本提取系統深度解析 1. 項目概述2. 技術原理與算法設計2.1 圖像預處理流水線2.2 表格結構檢測算法2.3 OCR優化策略 3. 實戰部署指南3.1 環境配置3.2 核心代碼解析3.3 執行流程示例 4. 常見問題與解決方案4.…

Redis BigKey 問題是什么

BigKey 問題是什么 BigKey 的具體表現是 redis 中的 key 對應的 value 很大&#xff0c;占用的 redis 空間比較大&#xff0c;本質上是大 value 問題。 BigKey怎么找 redis-cli --bigkeysscanBig Key 產生的原因 1.redis數據結構使用不恰當 2.未及時清理垃圾數據 3.對業務預…

go-gin

前置 gin是go的一個web框架&#xff0c;我們簡單介紹一下gin的使用 導入gin &#xff1a;"github.com/gin-gonic/gin" 我們使用import導入gin的包 簡單示例&#xff1a; package mainimport ("github.com/gin-gonic/gin" )func main() {r : gin.Default(…

C# NX二次開發:判斷兩個體是否干涉和獲取系統日志的UFUN函數

大家好&#xff0c;今天要講關于如何判斷兩個體是否干涉和獲取系統日志的UFUN函數。 &#xff08;1&#xff09;UF_MODL_check_interference&#xff1a;這個函數的定義為根據單個目標體檢查每個指定的工具體是否有干擾。 Defined in: uf_modl.h Overview Checks each sp…

如何解決 Linux 系統文件描述符耗盡的問題

在Linux系統中&#xff0c;文件描述符&#xff08;File Descriptor, FD&#xff09;是操作系統管理打開文件、套接字、管道等資源的抽象標識。當進程或系統耗盡文件描述符時&#xff0c;會導致服務崩潰、連接失敗等嚴重問題。以下是詳細的排查和解決方案&#xff1a; --- ###…

LVGL簡易計算器實戰

文章目錄 &#x1f4c1; 文件結構建議&#x1f539; eval.h 表達式求值頭文件&#x1f539; eval.c 表達式求值實現文件&#xff08;帶詳細注釋&#xff09;&#x1f539; ui.h 界面頭文件&#x1f539; ui.c 界面實現文件&#x1f539; main.c 主函數入口? 總結 項目效果&…

使用countDownLatch導致的線程安全問題,線程不安全的List-ArrayList,線程安全的List-CopyOnWriteArrayList

示例代碼 package com.example.demo.service;import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class UnSafeCDTest {Executor…

ALLinSSL:一站式SSL證書管理解決方案

引言 在當今互聯網安全日益重要的背景下,SSL證書已成為保護網站安全的必備工具。然而,管理多個SSL證書常常是一項繁瑣且容易出錯的任務。ALLinSSL應運而生,它提供了一個一站式的SSL證書管理解決方案,大大簡化了證書的申請、安裝和更新過程。本文將深入介紹ALLinSSL的特性、…

嵌入式通信協議總覽篇:萬物互聯的基石

嵌入式系統的世界,是靠協議“說話”的世界。 在你設計一個智能設備、構建一個工業控制系統、開發一款 IoT 網關時,一個核心問題始終繞不開:**這些設備之間如何“對話”?**答案就是——通信協議。 本篇作為系列第一章,將帶你全面理解嵌入式通信協議的全貌,為后續深入學習…

【數據結構】紅黑樹(C++)

目錄 一、紅黑樹的概念 二、紅黑樹的性質 三、紅黑樹結點定義 四、紅黑樹的操作 1. 插入操作 1.1 插入過程 1.2 調整過程 1.2.1 叔叔節點存在且為紅色 1.2.2 叔叔節點存在且為黑色 1.2.3 叔叔節點不存在 2. 查找操作 2.1 查找邏輯 2.2 算法流程圖 2.3 使用示例 …

Oracle數據庫DBF文件收縮

這兩天新部署了一套系統&#xff0c;數據庫結構保持不變&#xff0c;牽扯導出表結構還有函數&#xff0c;圖省事就直接新建用戶&#xff0c;還原數據庫了。然后咔咔咔&#xff0c;一頓刪除delete&#xff0c;truncate&#xff0c;發現要不就是表刪了&#xff0c;還有num_rows&a…

【字節擁抱開源】字節豆包團隊開源首發 Seed-Coder 大模型

我們非常高興地向大家介紹 Seed-Coder&#xff0c;它是一個功能強大、透明、參數高效的 8B 級開源代碼模型系列&#xff0c;包括基礎變體、指導變體和推理變體。Seed-Coder 通過以下亮點促進開放代碼模型的發展。 以模型為中心&#xff1a;Seed-Coder主要利用大語言模型&#…

Qt 無邊框窗口,支持貼邊分屏

常規操作, 無法進行窗口的大小縮放和移動貼邊分屏等操作 // 去掉標題欄,去掉工具欄&#xff0c;窗口置頂 setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);重點介紹 QWindowKit https://github.com/stdware/qwindowkit 跨平臺的支持Windows\…