前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在 XSwitch 中对接 GB28181 协议的摄像头

如何在 XSwitch 中对接 GB28181 协议的摄像头

作者头像
Seven Du
发布2024-03-19 14:15:19
3620
发布2024-03-19 14:15:19
举报
文章被收录于专栏:FreeSWITCH中文社区

随着视频监控应用的发展,涌现了大量的监控平台提供商,它们的接入协议各不相同,对不同厂商设备集中调阅的复杂度越来越高。在这样的产业背景下,GB/T28181 应运而生。

GB28181 定义了基于 SIP(会话初始协议)、SDP(会话描述协议)等协议的互联规范,安全注册、实时视音频点播等应用基于 SIP REGISTER、INVITE 等请求和响应方法。

配置 XSwitch 分机

进入【呼叫】⇨【分机】,新建一个分机,根据协议统一编码规则,应创建 20 位十进制数字字符号码,比如:34020000001320000005。

点击新创建的分机,进入分机详情页,修改类型海康摄像头,这样在呼叫该监控时,XSwitch 会自动添加Subject 消息头域以及正确的 SDP 信息。

需要说明一下,GB28181 设备或者平台一般不认域名,创建分机时需要单独配置一下域,一般取分机号码前 10 位即可。

监控摄像头配置

以海康摄像头为例,进入【配置】⇨【网络】⇨【高级配置】⇨【平台接入】,选择平台接入方式为28181,同时配置 SIP 服务器地址端口、用户名、ID、密码,启用并保存配置即可。

如果注册状态显示为在线则表示注册成功,如下图:

* 这里需要记住该处配置的SIP 服务器 ID,呼叫摄像头进行实时点播时会用到。

实时音视频点播

点播场景可以获取到设备的音视频,注意,设备是sendonly。如果想获取到设备的音频,设备需要选择复合流,否则 PS 流中只有视频。

路由配置

进入【呼叫】⇨【路由】,新建一条路由:

  • 名称:hk,也可以随意
  • 被叫字冠:340,根据上文提到的编码规则
  • 呼叫源:default
  • 最大长度:20
  • 目的地类型:本地分机

同时需要在号码变换中修改主叫号码变换为34020000001320000001

注意:

此处的主叫号码应该设置为上文中提及的SIP 服务器 ID,否则呼叫时,可能会收到415 Unsupported Media Type.

呼叫测试 使用xTalk或者 SIP 视频电话直接呼叫监控分机即可。

如果你想在终端fs_cli发起呼叫,可以直接:

代码语言:javascript
复制
bgapi originate {origination_caller_id_number=34020000001320000001}user/34020000001320000005 &conference(3000)

上述命令只有在分机类型选择为海康摄像头时才好用。

其实完整的命令应该是这样的:

代码语言:javascript
复制
bgapi originate {origination_caller_id_number=34020000001320000001,sip_h_Subject=34020000001320000005:0\,34020000001320000001:0,absolute_codec_string=PS}user/34020000001320000005 &conference(3000)

Subject各字段含义分别为媒体流发送者设备编码:发送端媒体流序列号,媒体流接收者设备编码:接收端媒体流序列号。

其中,媒体流发送者指的是摄像头,接收端指的是 XSwitch。

另外,我们看到这里设置的absolute_codec_stringPS,因此你需要检查一下 XSwitch 中是否已经成功加载mod_ps

如果对协商过程感兴趣,可以在终端fs_cli开启sofia global siptrace on或者参考 GB28181-2016 附录部分。

广播 广播场景下可以对设备喊话,注意,设备是recvonly

呼叫测试 广播发起方需要首先发送MESSAGE消息 Notify 设备,设备回复MESSAGE Response 后,会主动发送INVITE,所以需要配置对应的路由。

进入【呼叫】⇨【路由】新建一条路由,其中被叫号码为前文提及的SIP 服务器 ID,如果对接的是平台,真正的主叫设备 ID 在INVITE头部Subject字段中,from 则为平台注册到 XSwitch 的号码,平台会管理很多设备。

MESSAGE 参考:

代码语言:javascript
复制
MESSAGE sip:34020000001320000005@192.168.3.98:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.3.200;rport;branch=z9hG4bK1ap14K9Bmvrcg
Route: <sip:34020000001320000005@192.168.3.98:5060>
Max-Forwards: 70
From: "34020000001320000001" <sip:34020000001320000001@140.143.134.19:10160>;tag=1pN12ray0F6Ha
To: <sip:34020000001320000005@192.168.3.98:5060>
Call-ID: 6dcee39e-820d-4204-b890-8500b838188d
CSeq: 59825685 MESSAGE
User-Agent: FreeSWITCH-mod_sofia/1.10.8-dev+git~20221102T021101Z~fcab6ea333~64bit
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Type: Application/MANSCDP+xml
Content-Length: 185
X-FS-Sending-Message: 63e5e877-2fb6-4467-98ac-33de4cdd890a

<?xml version="1.0"?>
<Notify>
<CmdType>Broadcast</CmdType>
<SN>111</SN>
<SourceID>34020000001320000001</SourceID>
<TargetID>34020000001320000005</TargetID>
</Notify>

INVITE 参考:

代码语言:javascript
复制
INVITE sip:34020000001320000001@192.168.3.200:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.3.98:5060;rport;branch=z9hG4bK621100893
From: <sip:34020000001320000005@192.168.3.98:5060>;tag=1324899375
To: <sip:34020000001320000001@192.168.3.200:5060>
Call-ID: 1063016033
CSeq: 20 INVITE
Contact: <sip:34020000001320000005@192.168.3.98:5060>
Content-Type: application/sdp
Max-Forwards: 70
User-Agent: IP Camera
Subject: 34020000001320000001:1,34020000001320000005:2
Content-Length:   214

v=0
o=34020000001320000005 2260 2260 IN IP4 192.168.3.98
s=Play
c=IN IP4 192.168.3.98
t=0 0
m=audio 15062 RTP/AVP 8 96
a=recvonly
a=rtpmap:8 PCMA/8000
a=rtpmap:96 PS/90000
y=0200000017
f=v/////a/1/8/1

发送MESSAGE lua 脚本参考 broadcast.lua:

代码语言:javascript
复制
local body = ''
local sn = '111'
local source_id = '34020000001320000001'    -- 服务器编码 ID
local device_id = '34020000001320000005'    -- 设备编码 ID
local to = '34020000001320000005'           -- 平台注册到 FS 的号码(对接平台时为下级平台编码)或者跟 device_id 相同(直接对接设备)

local api = freeswitch.API()
local domain = api:execute("global_getvar", "domain")

body = '<?xml version="1.0" encoding="GB2312"?>\n' ..
        '<Notify>\n<CmdType>Broadcast</CmdType>\n<SN>'.. sn ..'</SN>\n<SourceID>' .. source_id ..'</SourceID>\n<TargetID>' .. device_id .. '</TargetID>\n' ..
        '</Notify>\n'

local event = freeswitch.Event("Custom", "SMS::SEND_MESSAGE");
event:addHeader('type', 'Application/MANSCDP+xml')
-- 对接平台时,平台可能不认 from 中的 domain
-- event:addHeader('from', source_id .. '@local_sip_ip:local_sip_port')
event:addHeader('from', source_id .. '@' .. domain)
event:addHeader('to', to .. '@' .. domain)
event:addHeader('sip_profile', 'default')
event:addHeader('dest_proto', 'sip')
event:addBody(body)
event:fire();

对讲 GB28181 对讲是基于点播和广播实现的,也就是说,对同一设备对讲需要两路呼叫来实现。

对讲测试 由于对讲基于点播和广播两路呼叫来实现,我们可以通过conference来实现。

首先,点播设备:

代码语言:javascript
复制
conference 3000 bgdial {origination_caller_id_number=34020000001320000001,sip_h_Subject=34020100001320000005:0\,34020000001320000001:0,absolute_codec_string=PS,conference_member_flags=mute}user/34020000001320000005

发起广播,需要将广播来话路由到同一个 conference 中:

代码语言:javascript
复制
lua broadcast.lua

呼叫普通 SIP 终端:

代码语言:javascript
复制
conference 3000 bgdial user/1009

由于点播+广播是两路呼叫,设备在 conference 中存在两个成员,这样点播到的音频会再次广播给设备,设备会啸叫。需要单独处理一下,点播设备时设置conference_member_flags=mute,这样谁也听不到设备的声音,然后:

代码语言:javascript
复制
conference 3000 relate id1 id2 nohear
conference 3000 unmute all

其中:id1对应广播成员,id2对应点播成员。

至此,对讲完成。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeSWITCH中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 呼叫测试 使用xTalk或者 SIP 视频电话直接呼叫监控分机即可。
  • 广播 广播场景下可以对设备喊话,注意,设备是recvonly。
  • 呼叫测试 广播发起方需要首先发送MESSAGE消息 Notify 设备,设备回复MESSAGE Response 后,会主动发送INVITE,所以需要配置对应的路由。
  • 对讲 GB28181 对讲是基于点播和广播实现的,也就是说,对同一设备对讲需要两路呼叫来实现。
    • 对讲测试 由于对讲基于点播和广播两路呼叫来实现,我们可以通过conference来实现。
    相关产品与服务
    云点播
    面向音视频、图片等媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档