国网B接口调阅实时视频(INVITE)接口描述和消息示例

article/2025/9/23 12:41:28

前面三篇blog分别介绍国网B接口注册、资源上报和资源信息获取,今天过一下国网B接口调阅实时视频相关的接口描述和消息示例,做过GB28181设备接入的都知道,国网B接口调阅实时视频流程和GB28181的基本一致的,区别在于SDP的一些参数描述,有些差别,举个例子,调阅实时视频,GB28181的SDP里面“s=Play”,国网B接口SDP取值定义“s=-”,如果严格按照规范来,估计好多系统都没法正常接入。

接口描述

国网B接口调阅实时视频,相关规范写的比较粗略:

调阅实时视频包括信令接口和媒体流接口,采用标准的SIP INVITE+SDP流程,媒体传输使用RTP/RTCP。

SDP 中 RTP Payload 的取值应遵守下面接口参数中的定义:

a) SDP 中的媒体信息,应仅有一个 m 行,用于描述视频格式。

b) 视频数据用 RTP 打包传输时,应考虑每个传输分组不大于 MTU,可采用的技术包括编码器层支持(如 ITU-T H.264 的 multi-slice 技术),或采用 RTP 层的分片机制(如 IETF RFC 3984 定义的 FU-A 技术)。

前端设备收到平台的INVITE请求后根据SDP描述进行媒体协商,协商通过后打开前端系统摄像机设备将获得的媒体流通过媒体通道发送到平台。

会话建立成功后,前端系统在某些特殊情况下可以主动结束当前呼叫。

平台应支持视频流的分发,以降低对前端系统的操作频繁性和节省网络带宽。

调阅实时视频的接口流程

主要功能流程如下:

a) F1:用户发送 INVITE 消息,携带 SDP 内容通过平台转发到前端设备。

b) F2:按照 SIP 要求,如前端系统在 0.5s 内未能处理该请求,则先发送 1xx 临时响应通过平台转发到用户。

c) F3:前端系统接受了调阅请求的操作,则发送携带 SDP 的 200 OK 响应通过平台转发到用户。

d) F4:用户发送 ACK 通过平台转发到前端设备。

e) 视频流从前端系统传输经平台转发到用户。

f) F5:用户结束会话,发送 BYE 消息到通过平台转发到前端系统。

g)F6:前端系统发送确认,将媒体通道拆线。

接口参数的重要SIP头字段和SIP响应码不再赘述,这里我们主要看看SDP的参数定义:

RTP动态Payload定义如下:

可以看到H.264的对应的Payload是100。

消息示例

调阅实时视频请求

INVITE sip:前端设备地址编码@前端系统所属平台域名或IP地址 SIP/2.0
From: <sip:用户地址编码@用户所属平台域名或IP地址>;tag=3101300
To: <sip:前端设备地址编码@前端系统所属平台域名或IP地址>
Contact: <sip:用户地址编码@用户所属平台域名或IP地址>
Call-ID: c47k42
Via: SIP/2.0/UDP 用户所属平台IP地址;branch=z9hG4bK
CSeq: 1 INVITE
Content-type: application/SDP
Content-Length: 消息体的长度
v=0
o=- 0 0 IN IP4 用户会话IP地址描述
s=-
c=IN IP4 用户媒体IP地址描述
m=video 13578 RTP/AVP 100
a=rtpmap:100 H264/90000
a=fmtp:100 CIF=1;4CIF=1;F=1;K=1
a=sendrecv

调阅实时视频请求响应

SIP/2.0 200 OK
From: <sip:用户地址编码@用户所属平台域名或IP地址>;tag=3101300
To: <sip:前端设备地址编码@前端系统所属平台域名或IP地址>;tag=20b0660
Contact: <sip:用户地址编码@前端系统所属平台域名或IP地址>
Call-ID: c47k42
Via: SIP/2.0/UDP 用户所属平台IP地址;branch=z9hG4bK
CSeq: 1 INVITE
Content-type: application/SDP
Content-Length: 消息体的长度
v=0
o=- 0 0 IN IP4 前端设备会话IP地址描述
s=-
c=IN IP4 前端设备媒体IP地址描述
m=video 1034 RTP/AVP 100
a=rtpmap:100 H264/90000
a=fmtp:100 CIF=1
a=fmtp:100 profile-level-id=420028;sprop-parameter-sets=Z0IAKO-kBQHsg,aM44gA==
a=sendrecv

国网B接口和GB28181的invite区别

我们再来看看,和GB28181的invite有什么不同之处:

GB/T28181-2016规范中,明确提到:实时视音频点播的SIP消息应通过本域或其他域的SIP服务器进行路由、转发,目标设备的实时视音频流宜通过本域内的媒体服务器进行转发。实时视音频点播采用SIP协议(IETFRFC3261)中的Invite方法实现会话连接,采用 RTP/RTCP协议(IETFRFC3550)实现媒体传输。

实时视音频点播的信令流程分为客户端主动发起和第三方呼叫控制两种方式,联网系统可选择其中一种或两种结合的实现方式。第三方呼叫控制的第三方控制者宜采用背靠背用户代理实现,有关第三方呼叫控制见IETFRFC3725。

实时视音频点播宜支持附录 M 规定的媒体流保活机制。

再看看GB28181客户端主动发起的实时视音频点播流程:

具体流程不再赘述,看看​​大牛直播SDK​​针对GB28181 invite的处理吧:

收到Invite后,除了正常信令交互回复外,初始化Sender():

@Overridepublic void ntsOnInvitePlay(String deviceId, SessionDescription session_des) {handler_.postDelayed(new Runnable() {@Overridepublic void run() {MediaSessionDescription video_des = null;SDPRtpMapAttribute ps_rtpmap_attr = null;// 28181 视频使用PS打包Vector<MediaSessionDescription> video_des_list = session_des_.getVideoPSDescriptions();if (video_des_list != null && !video_des_list.isEmpty()) {for(MediaSessionDescription m : video_des_list) {if (m != null && m.isValidAddressType() && m.isHasAddress() ) {video_des = m;ps_rtpmap_attr = video_des.getPSRtpMapAttribute();break;}}}if (null == video_des) {gb28181_agent_.respondPlayInvite(488, device_id_);Log.i(TAG, "ntsOnInvitePlay get video description is null, response 488, device_id:" + device_id_);return;}if (null == ps_rtpmap_attr) {gb28181_agent_.respondPlayInvite(488, device_id_);Log.i(TAG, "ntsOnInvitePlay get ps rtp map attribute is null, response 488, device_id:" + device_id_);return;}Log.i(TAG,"ntsOnInvitePlay, device_id:" +device_id_+", is_tcp:" + video_des.isRTPOverTCP()+ " rtp_port:" + video_des.getPort() + " ssrc:" + video_des.getSSRC()+ " address_type:" + video_des.getAddressType() + " address:" + video_des.getAddress());// 可以先给信令服务器发送临时振铃响应//sip_stack_android.respondPlayInvite(180, device_id_);long rtp_sender_handle = libPublisher.CreateRTPSender(0);if ( rtp_sender_handle == 0 ) {gb28181_agent_.respondPlayInvite(488, device_id_);Log.i(TAG, "ntsOnInvitePlay CreateRTPSender failed, response 488, device_id:" + device_id_);return;}gb28181_rtp_payload_type_  = ps_rtpmap_attr.getPayloadType();gb28181_rtp_encoding_name_ =  ps_rtpmap_attr.getEncodingName();libPublisher.SetRTPSenderTransportProtocol(rtp_sender_handle, video_des.isRTPOverUDP()?0:1);libPublisher.SetRTPSenderIPAddressType(rtp_sender_handle, video_des.isIPv4()?0:1);libPublisher.SetRTPSenderLocalPort(rtp_sender_handle, 0);libPublisher.SetRTPSenderSSRC(rtp_sender_handle, video_des.getSSRC());libPublisher.SetRTPSenderSocketSendBuffer(rtp_sender_handle, 2*1024*1024); // 设置到2MlibPublisher.SetRTPSenderClockRate(rtp_sender_handle, ps_rtpmap_attr.getClockRate());libPublisher.SetRTPSenderDestination(rtp_sender_handle, video_des.getAddress(), video_des.getPort());if ( libPublisher.InitRTPSender(rtp_sender_handle) != 0 ) {gb28181_agent_.respondPlayInvite(488, device_id_);libPublisher.DestoryRTPSender(rtp_sender_handle);return;}int local_port = libPublisher.GetRTPSenderLocalPort(rtp_sender_handle);if (local_port == 0) {gb28181_agent_.respondPlayInvite(488, device_id_);libPublisher.DestoryRTPSender(rtp_sender_handle);return;}Log.i(TAG,"get local_port:" + local_port);String local_ip_addr = IPAddrUtils.getIpAddress(context_);MediaSessionDescription local_video_des = new MediaSessionDescription(video_des.getType());local_video_des.addFormat(String.valueOf(ps_rtpmap_attr.getPayloadType()));local_video_des.addRtpMapAttribute(ps_rtpmap_attr);local_video_des.setAddressType(video_des.getAddressType());local_video_des.setAddress(local_ip_addr);local_video_des.setPort(local_port);local_video_des.setTransportProtocol(video_des.getTransportProtocol());local_video_des.setSSRC(video_des.getSSRC());if (!gb28181_agent_.respondPlayInviteOK(device_id_,local_video_des) ) {libPublisher.DestoryRTPSender(rtp_sender_handle);Log.e(TAG, "ntsOnInvitePlay call respondPlayInviteOK failed.");return;}gb28181_rtp_sender_handle_ = rtp_sender_handle;}private String device_id_;private SessionDescription session_des_;public Runnable set(String device_id, SessionDescription session_des) {this.device_id_ = device_id;this.session_des_ = session_des;return this;}}.set(deviceId, session_des),0);}

Ack后,开始初始化Pusher,发送数据到国标平台侧:

@Overridepublic void ntsOnAckPlay(String deviceId) {handler_.postDelayed(new Runnable() {@Overridepublic void run() {Log.i(TAG,"ntsOnACKPlay, device_id:" +device_id_);if (!isRTSPPublisherRunning && !isPushingRtmp && !isRecording) {InitAndSetConfig();}libPublisher.SetGB28181RTPSender(publisherHandle, gb28181_rtp_sender_handle_, gb28181_rtp_payload_type_, gb28181_rtp_encoding_name_);int startRet = libPublisher.StartGB28181MediaStream(publisherHandle);if (startRet != 0) {if (!isRTSPPublisherRunning && !isPushingRtmp  && !isRecording) {if (publisherHandle != 0) {libPublisher.SmartPublisherClose(publisherHandle);publisherHandle = 0;}}destoryRTPSender();Log.e(TAG, "Failed to start GB28181 service..");return;}if (!isRTSPPublisherRunning && !isPushingRtmp && !isRecording) {CheckInitAudioRecorder();}startLayerPostThread();isGB28181StreamRunning = true;}private String device_id_;public Runnable set(String device_id) {this.device_id_ = device_id;return this;}}.set(deviceId),0);}

以上是国网B接口调阅实时视频(INVITE)接口描述和消息示例,然后就GB28181的invite做了简单的对比,感兴趣的开发者,可以仔细研读两份规范,看看还有哪些不一致的地方。


http://chatgpt.dhexx.cn/article/jkekchSv.shtml

相关文章

SIP协议之PRACK机制

SIP PRACK&#xff08;Provisional Response ACKnowledgement&#xff09;是由SIP的扩展协议RFC3262定义的&#xff0c;旨在为SIP的临时应答提供传输的可靠性。扩展机制使用选项100rel和临时应答方法PRACK实现。该机制同SIP协议中的2xx对INVITE应答的可靠机制类似。 流程图&am…

HackTheBox: Arctic靶场

废话不多说直接开始&#xff1a; 第一步是在计算机上运行NMAP&#xff1a; # Nmap 7.80 scan initiated Sat Sep 19 14:54:46 2020 as: nmap -sV -O -sC -p- -oN scan 10.10.10.11 Nmap scan report for 10.10.10.11 Host is up (0.021s latency). Not shown: 65532 filtered…

webrtc sdp详解

SDP&#xff08;Session Description Protocol&#xff09;是一种通用的会话描述协议&#xff0c;主要用来描述多媒体会话&#xff0c;用途包括会话声明、会话邀请、会话初始化等。 WebRTC主要在连接建立阶段用到SDP&#xff0c;连接双方通过信令服务交换会话信息&#xff0c;…

SIP协议之呼叫流程

SIP呼呼叫是SIP协议最基本的功能。一个用户呼叫另外一个用户最终完成多媒体通话。此处以常见的B2BUA的服务器模式进行介绍。 环境说明&#xff1a; 主叫&#xff1a;1006 192.168.1.131 被叫&#xff1a;1012 192.168.0.24 SIP服务器&#xff08;以下简称服务器&#xff09;…

GB/T 28181-2011、2016、2022变更对比

一、GB/T 28181-2016与GB/T 28181-2011变更对比 GB/T 28181-2016与GB/T 28181-2011相比&#xff0c; 除编辑性修改外主要技术变化如下&#xff1a; ----(1) 修改了标准名称&#xff1b; ----(2) 增加了媒体流TCP传输要求(见4.3.1&#xff0c; 5.2&#xff0c;附录F&#xff…

会话描述协议-SDP

目录 一. 前言 二. 标准SDP规范说明 会话级描述 媒体级描述 三. WebRTC的SDP 会话描述 媒体信息描述 网络描述 安全描述 服务质量描述 四. 其他 一. 前言 SDP&#xff08;Session Description Protocol&#xff09; 是一种通用的会话描述协议&#xff0c;例如在音视…

h264和h265视频流SDP描述详解

文章目录 1 SDP概述 2.SDP媒体描述极其扩展属性 2.1 m属性介绍 2.2 acontrol附加属性介绍 2.3 artpmap附加属性介绍 2.4 afmtp附加属性介绍 SDP&#xff08;Session Description Protocol&#xff09;会话描述协议&#xff0c;是一种用来描述信息格式的标准&#xff0c;它…

表格标签

表格标签 规则表格 不规则表格–跨行和跨列 表格的高级标签–标题标签和逻辑分区标签

Android实现Excel表格样式

原理描述&#xff1a; 想写来着&#xff0c;但是似乎描述不太清楚。效果图来着&#xff0c;没找到好的视频录制软件&#xff0c;直接上代码吧。 代码&#xff1a; 1、xml布局文件 自定义控件的包名删除了部分&#xff0c;需要重新导入自定义控件&#xff01;&#xff01;&a…

Apache POI 操作Excel表格使用详解 最全

1.POI结构与常用类 (1)POI介绍 Apache POI是Apache软件基金会的开源项目&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。 (2)POI结构说明 包名称 说明 HSSF 提供…

022_Table表格

1. Table表格例子 1.1. Table表格用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作。 1.2. Table Attributes 参数 说明 类型 可选值 默认值 data 显示的数据 array 无 无 height Table的高度, 默认为自动高度。如果height为number类型…

java 导入导出excel表格

java 导入导出excel表格 业务上有需求上传excel表格并读取内容&#xff0c;本文记录一下该方法 表格导入 引入相应的工具包 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.4.0&l…

python逻辑回归

出现函数重名问题 异常抛出 异常抛出 #逻辑回归测试 import pandas as pd from sklearn.linear_model import LogisticRegression as LR filename C:/Users/29463/OneDrive/桌面/bankloan.xls data pd.read_excel(filename) #print(data) x data.iloc[:,:8].values y data…

实现带标题的ListView

在一些项目中&#xff0c;往往有要求为ListView里的内容分类&#xff0c;比如按日期分类&#xff0c;就要把相同日期的项目放在一起。可以看一些示例图&#xff0c;会清楚一些&#xff1a; 以上根据标题来进行分类&#xff0c;实现代码如下&#xff1a; 首先是数据项的模型…

java操作excel表格详解

在日常工作中&#xff0c;对Excel工作表格的操作处理可是多的数不清楚&#xff0c;下面是java语言对其的操作&#xff0c;有需要的小伙伴可以参考下 使用场景 1、将用户信息导出为excel表格&#xff08;导出数据…) 2、将Excel表中的信息录入到网站数据库(习题上传…&#xf…

安卓表格框架-ExcelView

转载请标明来源&#xff1a;安卓表格框架-ExcelView_分享记录-CSDN博客 Github地址&#xff0c;欢迎star&#xff1a;https://github.com/September26/ExcelView 一.项目介绍 项目是仿照WPS中Excel的功能实现的&#xff0c;实现了显示&#xff0c;滑动&#xff0c;编辑等基本…

html表格打印填充分页,window.print()页面打印之表格内容分页填充进行分页打印

windwow.print()用于打印当前窗口的内容,很简便,可当内容特殊并且打印有特殊需求的时候就要绕个圈了。下面是需要打印的表格: 当数据量少的时候像上面的表格一样,中间的内容只有5条数据,打印出来在纸上会有空白,不太好。中间内容是不确定的可能几十条,可能上百条,这样循…

在线表格

在线表格案例 模仿的是腾讯文档 首先观察腾讯文档的表格效果&#xff0c;然后在构建出思路&#xff0c;开始编写代码 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title>在线表格<…

Java获取word表格中的数据

前言: 有时系统中需要提取各种文件中的数据&#xff0c;比如做报表的系统中就常常与Excel表格数据做交互。做Excel报表数据时有选择POI实现的&#xff0c;但是POI功能也很单一&#xff0c;对于文档格式维护性差&#xff0c;最重要的是POI在操作word数据时显得力不从心&#xf…

HTML 表格元素

表格元素 在日常生活中&#xff0c;我们对表格已经非常熟悉了&#xff0c;表格的基本作用是用来存放数据&#xff0c;它是数据的二维容器&#xff0c;人们常常用它来记录财务数据、列车时刻表、电视节目单等。 大多数情况下&#xff0c;表格都是由列标题或行标题&#xff0c;…