package gb28181 import ( "bytes" "encoding/xml" "fmt" "golang.org/x/net/html/charset" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "strconv" "time" ) const ( // CatalogXML 获取设备列表xml样式 CatalogXML = ` Catalog %d %s ` // RecordInfoXML 获取录像文件列表xml样式 RecordInfoXML = ` RecordInfo %d %s %s %s 0 all ` // DeviceInfoXML 查询设备详情xml样式 DeviceInfoXML = ` DeviceInfo %d %s ` // DevicePositionXML 订阅设备位置 DevicePositionXML = ` MobilePosition %d %s %d ` AlarmResponseXML = ` Alarm 17430 %s ` ChannelOnStatus ChannelStatus = "ON" ChannelOffStatus ChannelStatus = "OFF" ) func intTotime(t int64) time.Time { tstr := strconv.FormatInt(t, 10) if len(tstr) == 10 { return time.Unix(t, 0) } if len(tstr) == 13 { return time.UnixMilli(t) } return time.Now() } // BuildDeviceInfoXML 获取设备详情指令 func BuildDeviceInfoXML(sn int, id string) string { return fmt.Sprintf(DeviceInfoXML, sn, id) } // BuildCatalogXML 获取NVR下设备列表指令 func BuildCatalogXML(sn int, id string) string { return fmt.Sprintf(CatalogXML, sn, id) } // BuildRecordInfoXML 获取录像文件列表指令 func BuildRecordInfoXML(sn int, id string, start, end int64) string { return fmt.Sprintf(RecordInfoXML, sn, id, intTotime(start).Format("2006-01-02T15:04:05"), intTotime(end).Format("2006-01-02T15:04:05")) } // BuildDevicePositionXML 订阅设备位置 func BuildDevicePositionXML(sn int, id string, interval int) string { return fmt.Sprintf(DevicePositionXML, sn, id, interval) } func BuildAlarmResponseXML(id string) string { return fmt.Sprintf(AlarmResponseXML, id) } type ( ChannelStatus string Record struct { DeviceID string Name string FilePath string Address string StartTime string EndTime string Secrecy int Type string } ChannelInfo struct { DeviceID string // 通道ID ParentID string Name string Manufacturer string Model string Owner string CivilCode string Address string Port int Parental int SafetyWay int RegisterWay int Secrecy int Status ChannelStatus } Message struct { XMLName xml.Name CmdType string SN int // 请求序列号,一般用于对应 request 和 response DeviceID string DeviceName string Manufacturer string Model string Channel string DeviceList []ChannelInfo `xml:"DeviceList>Item"` RecordList []Record `xml:"RecordList>Item"` SumNum int // 录像结果的总数 SumNum,录像结果会按照多条消息返回,可用于判断是否全部返回 } ) func DecodeGB2312(v any, body []byte) error { decoder := xml.NewDecoder(bytes.NewReader(body)) decoder.CharsetReader = charset.NewReaderLabel return decoder.Decode(v) } func DecodeGbk(v any, body []byte) error { decoder := xml.NewDecoder(transform.NewReader(bytes.NewReader(body), simplifiedchinese.GBK.NewDecoder())) decoder.CharsetReader = charset.NewReaderLabel return decoder.Decode(v) }