国标抓图

This commit is contained in:
xugo
2025-03-30 22:59:20 +08:00
parent f8cc68a196
commit 73885f10fc
9 changed files with 159 additions and 23 deletions
+41 -13
View File
@@ -3,6 +3,7 @@ package gbs
import (
"encoding/hex"
"encoding/xml"
"fmt"
"log/slog"
"math"
@@ -33,16 +34,15 @@ const (
// AlarmReport = "AlarmReport"
// // OSDConfig 前端OSD设置
// OSDConfig = "OSDConfig"
// // SnapShotConfig 图像抓拍配置
// SnapShotConfig = "SnapShotConfig"
)
type ConfigDownloadRequest struct {
XMLName xml.Name `xml:"Query"`
CmdType string `xml:"CmdType"` // 命令类型:设备配置查询(必选)
SN int32 `xml:"SN"` // 命令序列号(必选)
DeviceID string `xml:"DeviceID"` // 目标设备编码(必选)
ConfigType string `xml:"ConfigType"` // 查询配置参数类型(必选)
XMLName xml.Name `xml:"Query"`
CmdType string `xml:"CmdType"` // 命令类型:设备配置查询(必选)
SN int32 `xml:"SN"` // 命令序列号(必选)
DeviceID string `xml:"DeviceID"` // 目标设备编码(必选)
ConfigType string `xml:"ConfigType"` // 查询配置参数类型(必选)
SnapShotConfig *SnapShot `xml:"SnapShotConfig"`
}
type ConfigDownloadResponse struct {
@@ -62,7 +62,14 @@ type ConfigDownloadResponse struct {
// FrameMirror *FrameMirror `xml:"FrameMirror"`
// AlarmReport *AlarmReport `xml:"AlarmReport"`
// OSDConfig *OSDConfig `xml:"OSDConfig"`
// SnapShot *SnapShot `xml:"SnapShot"`
SnapShot *SnapShot `xml:"SnapShot"`
}
type SnapShot struct {
SnapNum int `xml:"SnapNum"` // 连拍张数(必选),最多10张,当手动抓拍时,取值为1
Interval int `xml:"Interval"` // 单张抓拍间隔时间,单位:秒(必选),取值范围:最短1秒
UploadURL string `xml:"UploadURL"` // 抓拍图像上传路径(必选)
SessionID string `xml:"SessionID"` // 会话ID,由平台生成,用于关联抓拍的图像与平台请求(必选)
}
// BasicParam 设备基本参数配置
@@ -73,25 +80,27 @@ type BasicParam struct {
HeartBeatCount int `xml:"HeartBeatCount"` // 心跳超时次数
}
func NewConfigDownloadRequest(sn int32, deviceID string, configType string) []byte {
const CMDTypeConfigDownload = "ConfigDownload"
func NewBasicParamRequest(sn int32, deviceID string) []byte {
c := ConfigDownloadRequest{
CmdType: "ConfigDownload",
CmdType: CMDTypeConfigDownload,
SN: sn,
DeviceID: deviceID,
ConfigType: configType,
ConfigType: basicParam,
}
xmlData, _ := sip.XMLEncode(c)
return xmlData
}
func (g *GB28181API) QueryConfigDownloadBasic(deviceID, configType string) error {
func (g *GB28181API) QueryConfigDownloadBasic(deviceID string) error {
slog.Debug("QueryConfigDownloadBasic", "deviceID", deviceID)
ipc, ok := g.svr.memoryStorer.Load(deviceID)
if !ok {
return ErrDeviceOffline
}
tx, err := g.svr.wrapRequest(ipc, sip.MethodMessage, &sip.ContentTypeXML, NewConfigDownloadRequest(1, deviceID, configType))
tx, err := g.svr.wrapRequest(ipc, sip.MethodMessage, &sip.ContentTypeXML, NewBasicParamRequest(1, deviceID))
if err != nil {
return err
}
@@ -99,6 +108,25 @@ func (g *GB28181API) QueryConfigDownloadBasic(deviceID, configType string) error
return err
}
func (g *GB28181API) handleDeviceConfig(ctx *sip.Context) {
slog.Debug("handleDeviceConfig", "deviceID", ctx.DeviceID)
b := ctx.Request.Body()
fmt.Println(">>>", string(b))
// var msg DeviceConfigResponse
// if err := sip.XMLDecode(ctx.Request.Body(), &msg); err != nil {
// ctx.Log.Error("handleDeviceConfig", "err", err, "body", hex.EncodeToString(ctx.Request.Body()))
// ctx.String(400, ErrXMLDecode.Error())
// return
// }
// if msg.SnapShotConfig != nil {
// slog.Debug("handleDeviceConfig", "snapShotConfig", msg.SnapShotConfig)
// }
ctx.String(200, "OK")
}
func (g *GB28181API) sipMessageConfigDownload(ctx *sip.Context) {
slog.Debug("sipMessageConfigDownload", "deviceID", ctx.DeviceID)
+29
View File
@@ -0,0 +1,29 @@
package gbs
import (
"log/slog"
"github.com/gowvp/gb28181/pkg/gbs/sip"
)
func (g *GB28181API) QuerySnapshot(deviceID, channelID string) error {
slog.Debug("QuerySnapshot", "deviceID", deviceID)
ipc, ok := g.svr.memoryStorer.Load(deviceID)
if !ok {
return ErrDeviceOffline
}
body := NewDeviceConfig(channelID).SetSnapShotConfig(&SnapShot{
SnapNum: 1,
Interval: 1,
UploadURL: "http://192.168.10.31:15123/gb28181/snapshot",
SessionID: "1234567890",
}).Marshal()
tx, err := g.svr.wrapRequest(ipc, sip.MethodMessage, &sip.ContentTypeXML, body)
if err != nil {
return err
}
_, err = sipResponse(tx)
return err
}
+37
View File
@@ -0,0 +1,37 @@
package gbs
import "encoding/xml"
const snapShotConfig = "SnapShotConfig" // 图像抓拍配置
// 设备配置 A.2.3.2.1
type DeviceConfigRequest struct {
XMLName xml.Name `xml:"Control"`
CmdType string `xml:"CmdType"` // 命令类型:设备配置查询(必选)
SN int32 `xml:"SN"` // 命令序列号(必选)
DeviceID string `xml:"DeviceID"` // 目标设备编码(必选)
SnapShotConfig *SnapShot `xml:"SnapShotConfig"`
}
func NewDeviceConfig(deviceID string) *DeviceConfigRequest {
return &DeviceConfigRequest{
CmdType: "DeviceConfig",
SN: 1,
DeviceID: deviceID,
}
}
func (d *DeviceConfigRequest) SetSN(sn int32) *DeviceConfigRequest {
d.SN = sn
return d
}
func (d *DeviceConfigRequest) SetSnapShotConfig(snapShot *SnapShot) *DeviceConfigRequest {
d.SnapShotConfig = snapShot
return d
}
func (d *DeviceConfigRequest) Marshal() []byte {
b, _ := xml.Marshal(d)
return b
}
+1 -1
View File
@@ -151,7 +151,7 @@ func (g *GB28181API) handlerRegister(ctx *sip.Context) {
g.QueryDeviceInfo(ctx)
_ = g.QueryCatalog(dev.DeviceID)
_ = g.QueryConfigDownloadBasic(dev.DeviceID, basicParam)
_ = g.QueryConfigDownloadBasic(dev.DeviceID)
}
func (g GB28181API) login(ctx *sip.Context, expire string) {
+6
View File
@@ -59,6 +59,7 @@ func NewServer(cfg *conf.Bootstrap, store gb28181.GB28181, sc sms.Core) (*Server
msg.Handle("Catalog", api.sipMessageCatalog)
msg.Handle("DeviceInfo", api.sipMessageDeviceInfo)
msg.Handle("ConfigDownload", api.sipMessageConfigDownload)
msg.Handle("DeviceConfig", api.handleDeviceConfig)
// msg.Handle("RecordInfo", api.handlerMessage)
@@ -214,3 +215,8 @@ func (s *Server) Play(in *PlayInput) error {
func (s *Server) StopPlay(in *StopPlayInput) error {
return s.gb.StopPlay(in)
}
// QuerySnapshot 厂商实现抓图的少,sip 层已实现,先搁置
func (s *Server) QuerySnapshot(deviceID, channelID string) error {
return s.gb.QuerySnapshot(deviceID, channelID)
}