chenshijun
2019-06-20 ebd6497f7eaf0cb29001245f8d685ad1775cf193
first vervion
1个文件已修改
6个文件已添加
564 ■■■■■ 已修改文件
README.md 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api_test.go 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
client.go 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
clientFactory.go 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
entites.go 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gb28181Api.go 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
httpClient.go 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -2,3 +2,6 @@
国标28181的api
API:gb28181Api.go
传输:httpClient.go
使用接口前需要执行Init(),指定ip+port
api_test.go
New file
@@ -0,0 +1,68 @@
package gb28181api
import (
    "fmt"
    "testing"
)
func TestSetPlatformServerInfo(t *testing.T) {
    var api Gb28181Api
    var gbserverinfo = GbServerInfo{
        Name:           "测试国标平台",
        PublicID:       "44120000002000000011",
        GbServerPort:   7060,
        RtspServrPort:  7554,
        HTTPClientIP:   "",
        HTTPClientPort: 0,
    }
    Init("192.168.1.203", 8060)
    flag := api.SetPlatformServerInfo(gbserverinfo)
    fmt.Println(flag)
}
func TestGetPlatformServerInfo(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    gbserverinfo, flag := api.GetPlatformServerInfo()
    fmt.Println("flag:", flag)
    fmt.Println("gbserverinfo:", SmartPrintStruct(gbserverinfo))
}
func TestGetDevicesByPageNO(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    devsinfo, flag := api.GetDevicesByPageNO(1)
    fmt.Println("flag:", flag)
    fmt.Println("devsinfo:", SmartPrintStruct(devsinfo))
}
func TestGetAllDevices(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    alldevsinfo, flag := api.GetAllDevices()
    fmt.Println("flag:", flag)
    fmt.Println("alldevsinfo:", SmartPrintStruct(alldevsinfo))
}
func TestGetCamsByDevAndPage(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    camsinfo, flag := api.GetCamsByDevAndPage("44122500042001000123", "all", 1)
    fmt.Println("flag:", flag)
    fmt.Println("camsinfo:", SmartPrintStruct(camsinfo))
}
func TestGetAllCamerasByDevID(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    allcamsinfo, flag := api.GetAllCamerasByDevID("44122500042001000123")
    fmt.Println("flag:", flag)
    fmt.Println("allcamsinfo:", SmartPrintStruct(allcamsinfo))
}
func TestSetCameraPtz(t *testing.T) {
    var api Gb28181Api
    Init("192.168.1.203", 8060)
    flag := api.SetCameraPtz("11010202081314000004", "focusnear", 150)
    fmt.Println("flag:", flag)
}
client.go
New file
@@ -0,0 +1,30 @@
package gb28181api
import (
    "strconv"
)
type Client interface {
    //GET
    DoGetRequest(url string, params map[string]string, headers map[string]string) ([]byte, error)
    //POST
    DoPostRequest(url string, contentType string, body map[string]interface{}, params map[string]string, headers map[string]string) ([]byte, error)
    //PUT
    DoPutRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error)
    //DELETE
    DoDeleteRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error)
}
var BASIC_URL = "http://192.168.1.203:8060"
const (
    DATA_URL_PREFIX      = "/vssconfig"
    CONTENT_TYPE_FORM    = "application/x-www-form-urlencoded"
    CONTENT_TYPE_MULFORM = "multipart/form-data"
    CONTENT_TYPE_JSON    = "application/json"
)
//初始化dbserver的地址和端口
func Init(ip string, port int) {
    BASIC_URL = "http://" + ip + ":" + strconv.Itoa(port)
}
clientFactory.go
New file
@@ -0,0 +1,9 @@
package gb28181api
//Factory new client
func NewClient() Client {
    var client Client
    client = &HttpClient{}
    //client = &ReqRepClient{}
    return client
}
entites.go
New file
@@ -0,0 +1,75 @@
package gb28181api
//GbServerInfo 国标平台信息
type GbServerInfo struct {
    Name           string `json:"name"`           //国标平台的名称
    PublicID       string `json:"publicid"`       //国标平台的20位ID (200类型)
    GbServerPort   int    `json:"gbserverport"`   //国标平台监听的端口
    RtspServrPort  int    `json:"rtspservrport"`  //RTSP服务的端口
    HTTPClientIP   string `json:"httpclientip"`   //HTTP客户端的ip(用于报警通知,一般不设置)
    HTTPClientPort int    `json:"httpclientport"` //HTTP客户端的端口(用于报警通知,一般不设置)
}
//GbResult 返回值信息
type GbResult struct {
    ErrCode int    `json:"errcode"`
    ErrDesc string `json:"errdesc"`
}
//DeviceInfo 下级设备信息
type DeviceInfo struct {
    PublicID string `json:"publicid"` //(字符串)   国标设备20位id
    Name     string `json:"name"`     //(字符串)   资源名称
    Alive    int    `json:"alive"`    //(数字)        状态 0:不在线 1:在线
    Corp     string `json:"corp"`     //(字符串)   厂商
    Parentid string `json:"parentid"` //(字符串)   父节点id
    IP       string `json:"ip"`       //(字符串)   ip地址
    Port     int    `json:"port"`     //(数字)     端口
    Username string `json:"username"` //(字符串)   设备注册用户名
    Passwd   string `json:"passwd"`   //(字符串)   设备注册密码
    Devmode  string `json:"devmode"`  //(字符串)   设备类型
}
//DevicesInOnePage 一页的下级设备信息
type DevicesInOnePage struct {
    GbResult
    TotalSize   int          `json:"totalsize"`   //(数字)   设备总数  (下同)
    OnePageSize int          `json:"onepagesize"` //(数字)   每页大小  (下同)
    TotalPage   int          `json:"totalpage"`   //(数字)   总分页数  (下同)
    PageNO      int          `json:"pageno"`      //(数字)   当前第几页(下同)
    Count       int          `json:"count"`       //(数字)   当前有几条数据(下同)
    Data        []DeviceInfo `json:"data"`        //设备信息,参照“1.设备管理”定义
}
//CameraInfo 摄像机信息
type CameraInfo struct {
    ResType     int     `json:"restype"`     //(数字)     1-通道资源 2-资源组
    PublicID    string  `json:"publicid"`    //(字符串)   国标资源通道20位id (用于请求视频、控制等操作)
    Name        string  `json:"name"`        //(字符串)   资源名称
    Alive       int     `json:"alive"`       //(数字)      状态 0:不在线 1:在线
    Corp        string  `json:"corp"`        //(字符串)      厂商
    Model       string  `json:"model"`       //(字符串)   设备类型
    Owner       string  `json:"owner"`       //(字符串)   设备归属
    CivilCode   string  `json:"civilcode"`   //(字符串)      行政区域 (可以按照行政区域进行划分资源组)
    Address     string  `json:"address"`     //(字符串)      地址
    DevPubID    string  `json:"devpubid"`    //(字符串)      通道的设备id
    ParentID    string  `json:"parentid"`    //(字符串)      父节点id
    IP          string  `json:"ip"`          //(字符串)   ip地址
    Port        int     `json:"port"`        //(数字)     端口
    Longitude   float64 `json:"longitude"`   //(数字)     经度
    Latitude    float64 `json:"latitude"`    //(数字)     纬度
    PtzType     int     `json:"ptztype"`     //(数字)     控制类型 1-球机;2-半球;3-固定枪机;4-遥控枪机;
    StreamType  int     `json:"streamtype"`  //(数字)     码流类型 0-H264;1-MPEG2;2-MPEG4;3-SVAC;4-3GP;5-H265;
    RealRtspURL string  `json:"realrtspurl"` //(字符串)   实时视频的rtsp地址
}
//CamerasInOnePage 一页的摄像机信息
type CamerasInOnePage struct {
    GbResult
    TotalSize   int          `json:"totalsize"`   //(数字)   设备总数  (下同)
    OnePageSize int          `json:"onepagesize"` //(数字)   每页大小  (下同)
    TotalPage   int          `json:"totalpage"`   //(数字)   总分页数  (下同)
    PageNO      int          `json:"pageno"`      //(数字)   当前第几页(下同)
    Count       int          `json:"count"`       //(数字)   当前有几条数据(下同)
    Data        []CameraInfo `json:"data"`        //设备信息,参照“1.设备管理”定义
}
gb28181Api.go
New file
@@ -0,0 +1,224 @@
package gb28181api
import (
    "bytes"
    "encoding/json"
    "fmt"
    "strconv"
)
func SmartPrintStruct(src interface{}) string {
    b, err := json.Marshal(src)
    if err != nil {
        return fmt.Sprintf("%+v", src)
    }
    var out bytes.Buffer
    err = json.Indent(&out, b, "", "    ")
    if err != nil {
        return fmt.Sprintf("%+v", src)
    }
    return out.String()
}
type Gb28181Api struct{}
//SetPlatformServerInfo 设置服务器信息
func (api Gb28181Api) SetPlatformServerInfo(serverInfo GbServerInfo) bool {
    url := BASIC_URL + DATA_URL_PREFIX + "/set_platform_server"
    client := NewClient()
    paramBody := make(map[string]string, 0)
    paramBody["gbsvrid"] = serverInfo.PublicID
    paramBody["gbsvrport"] = strconv.Itoa(serverInfo.GbServerPort)
    paramBody["gbsvrname"] = serverInfo.Name
    paramBody["rtspsvrport"] = strconv.Itoa(serverInfo.RtspServrPort)
    // fmt.Println("url:", url)
    body, err := client.DoGetRequest(url, paramBody, nil)
    if err != nil {
        return false
    }
    var res GbResult
    // fmt.Println("body", string(body))
    if err = json.Unmarshal(body, &res); err != nil {
        fmt.Println("jsonErr:", err)
        return false
    }
    if res.ErrCode != 0 {
        fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc)
        return false
    }
    return true
}
type retGbServerInfo struct {
    GbServerInfo
    GbResult
}
//GetPlatformServerInfo 获取服务器信息
func (api Gb28181Api) GetPlatformServerInfo() (GbServerInfo, bool) {
    url := BASIC_URL + DATA_URL_PREFIX + "/get_platform_server"
    client := NewClient()
    var info GbServerInfo
    body, err := client.DoGetRequest(url, nil, nil)
    if err != nil {
        fmt.Println("err:", err)
        return info, false
    }
    //解析retGbServerInfo
    var res retGbServerInfo
    if err = json.Unmarshal(body, &res); err != nil {
        fmt.Println("jsonErr:", err)
        return info, false
    }
    if res.ErrCode != 0 {
        fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc)
        return info, false
    }
    return res.GbServerInfo, true
}
//GetDevicesByPageNO 按页获取下级设备(平台或摄像机)列表
//pageNo (数字)   指定获取第几页,第一次为1,返回总页数,总条数等,再根据这些信息去再次查询,直到取完全部
func (api Gb28181Api) GetDevicesByPageNO(pageNo int) (DevicesInOnePage, bool) {
    url := BASIC_URL + DATA_URL_PREFIX + "/get_all_device/" + strconv.Itoa(pageNo)
    client := NewClient()
    var devicesPerPage DevicesInOnePage
    body, err := client.DoGetRequest(url, nil, nil)
    if err != nil {
        fmt.Println("err:", err)
        return devicesPerPage, false
    }
    //解析 DevicesInOnePage
    if err = json.Unmarshal(body, &devicesPerPage); err != nil {
        fmt.Println("jsonErr:", err)
        return devicesPerPage, false
    }
    if devicesPerPage.ErrCode != 0 {
        fmt.Println("errcode: ", devicesPerPage.ErrCode, " errdesc: ", devicesPerPage.ErrDesc)
        return devicesPerPage, false
    }
    return devicesPerPage, true
}
//GetAllDevices 获取全部下级设备(平台或摄像机)信息列表
func (api Gb28181Api) GetAllDevices() ([]DeviceInfo, bool) {
    var deviceSlice []DeviceInfo
    devicesPerPage, flag := api.GetDevicesByPageNO(1)
    if !flag {
        fmt.Println("GetDevicesByPageNO Error, deviceSlice is nil")
        return deviceSlice, false
    }
    deviceSlice = devicesPerPage.Data
    for i := 1; i < devicesPerPage.TotalPage; i++ {
        devicesPerPage, flag := api.GetDevicesByPageNO(i + 1)
        if !flag {
            fmt.Println("GetDevicesByPageNO Error,pageno:" + strconv.Itoa(i+1) + " ,deviceSlice is not completed")
            return deviceSlice, false
        }
        deviceSlice = append(deviceSlice, devicesPerPage.Data...)
    }
    return deviceSlice, true
}
//GetCamsByDevAndPage 按页获取下级设备的摄像机列表
//devID  (字符串)  注册的设备的20位id
//pageNo (数字)   指定获取第几页,第一次为1,返回总页数,总条数等,再根据这些信息去再次查询,直到取完全部
//srcType (字符串) "all"-表示获取设备的所有资源  "node"-父节点下的第一级资源
//注意:根据"restype"字段,忽略资源组,只保留通道资源------"restype":(数字)1-通道资源 2-资源组
func (api Gb28181Api) GetCamsByDevAndPage(devID string, srcType string, pageNo int) (CamerasInOnePage, bool) {
    url := BASIC_URL + DATA_URL_PREFIX + "/get_all_channel/" + devID + "/" + srcType + "/" + strconv.Itoa(pageNo)
    client := NewClient()
    var camerasPerPage CamerasInOnePage
    body, err := client.DoGetRequest(url, nil, nil)
    if err != nil {
        fmt.Println("err:", err)
        return camerasPerPage, false
    }
    //解析 CamerasInOnePage
    if err = json.Unmarshal(body, &camerasPerPage); err != nil {
        fmt.Println("jsonErr:", err)
        return camerasPerPage, false
    }
    if camerasPerPage.ErrCode != 0 {
        fmt.Println("errcode: ", camerasPerPage.ErrCode, " errdesc: ", camerasPerPage.ErrDesc)
        return camerasPerPage, false
    }
    if len(camerasPerPage.Data) > 0 {
        for i, v := range camerasPerPage.Data {
            if v.ResType == 2 {
                fmt.Println("v.restype == 2")
                camerasPerPage.Data = append(camerasPerPage.Data[:i], camerasPerPage.Data[i+1:]...)
            }
        }
    }
    return camerasPerPage, true
}
//GetAllCamerasByDevID 获取全部下级设备的摄像机列表
//devID  (字符串)  注册的设备的20位id
func (api Gb28181Api) GetAllCamerasByDevID(devID string) ([]CameraInfo, bool) {
    var cameraSlice []CameraInfo
    camerasPerPage, flag := api.GetCamsByDevAndPage(devID, "all", 1)
    if !flag {
        fmt.Println("GetCamsByDevAndPage Error, deviceSlice is nil")
        return cameraSlice, false
    }
    cameraSlice = camerasPerPage.Data
    for i := 1; i < camerasPerPage.TotalPage; i++ {
        camerasPerPage, flag := api.GetCamsByDevAndPage(devID, "all", i+1)
        if !flag {
            fmt.Println("GetCamsByDevAndPage Error! devID:" + devID + ",type:all,pageno:" + strconv.Itoa(i+1) + " ,cameraSlice is not completed")
            return cameraSlice, false
        }
        cameraSlice = append(cameraSlice, camerasPerPage.Data...)
    }
    return cameraSlice, true
}
//SetCameraPtz 2.3 PTZ云台控制
//"channelid":  (字符串)   通道20位编号
//"ptztype":   (字符串) 控制类型:上"up",下"down",左"left",右"right",左上"leftup",左下"leftdown",右上"rightup",右下"rightdown",镜头近"zoomin",镜头远"zoomout",
//                焦距远"focusfar",焦距近"focusnear", 设置预置位"setpos",调预置位"callpos",停止"stop"
//"ptzparam":   (数字)   参数,速度范围为1-255
func (api Gb28181Api) SetCameraPtz(chanID string, ptzType string, ptzParam int) bool {
    url := BASIC_URL + "/vss/ptz/" + ptzType + "/" + strconv.Itoa(ptzParam) + "/" + chanID
    client := NewClient()
    body, err := client.DoGetRequest(url, nil, nil)
    if err != nil {
        fmt.Println("err:", err)
        return false
    }
    //解析 CamerasInOnePage
    var res GbResult
    if err = json.Unmarshal(body, &res); err != nil {
        fmt.Println("jsonErr:", err)
        return false
    }
    if res.ErrCode != 0 {
        fmt.Println("errcode: ", res.ErrCode, " errdesc: ", res.ErrDesc)
        return false
    }
    return true
}
httpClient.go
New file
@@ -0,0 +1,155 @@
package gb28181api
import (
    "bytes"
    "encoding/json"
    "io/ioutil"
    "log"
    "net/http"
)
type HttpClient struct{}
//发起GET请求
func (httpApi HttpClient) DoGetRequest(url string, params map[string]string, headers map[string]string) ([]byte, error) {
    var body []byte
    request, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return body, err
    }
    // add params
    query := request.URL.Query()
    if params != nil {
        for key, val := range params {
            query.Add(key, val)
        }
        request.URL.RawQuery = query.Encode()
    }
    //add headers
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        return body, err
    }
    defer resp.Body.Close()
    body, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return body, err
    }
    return body, nil
}
//发起POST请求
func (httpApi HttpClient) DoPostRequest(url string, contentType string, body map[string]interface{}, params map[string]string, headers map[string]string) ([]byte, error) {
    var resultBytes []byte
    var bodyJson []byte
    if body != nil {
        var err error
        bodyJson, err = json.Marshal(body)
        if err != nil {
            return resultBytes, err
        }
    }
    request, err := http.NewRequest("POST", url, bytes.NewBuffer(bodyJson))
    if err != nil {
        return resultBytes, err
    }
    request.Header.Set("Content-type", contentType)
    //add params
    q := request.URL.Query()
    if params != nil {
        for key, val := range params {
            q.Add(key, val)
        }
        request.URL.RawQuery = q.Encode()
    }
    // add headers
    if headers != nil {
        for key, val := range headers {
            request.Header.Add(key, val)
        }
    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        return resultBytes, err
    }
    defer resp.Body.Close()
    resultBytes, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return resultBytes, err
    }
    return resultBytes, nil
}
//构造put请求
func (httpApi HttpClient) DoPutRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) {
    var resultBytes []byte
    var bodyJson []byte
    if body != nil {
        var err error
        bodyJson, err = json.Marshal(body)
        if err != nil {
            return resultBytes, err
        }
    }
    request, err := http.NewRequest("PUT", url, bytes.NewBuffer(bodyJson))
    if err != nil {
        log.Println(err)
        return resultBytes, err
    }
    request.Header.Set("Content-type", contentType)
    // add headers
    if headers != nil {
        for key, val := range headers {
            request.Header.Add(key, val)
        }
    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        return resultBytes, err
    }
    defer resp.Body.Close()
    resultBytes, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return resultBytes, err
    }
    return resultBytes, nil
}
//构造delete请求
func (httpApi HttpClient) DoDeleteRequest(url string, contentType string, body map[string]interface{}, headers map[string]string) ([]byte, error) {
    var resultBytes []byte
    var bodyJson []byte
    if body != nil {
        var err error
        bodyJson, err = json.Marshal(body)
        if err != nil {
            return resultBytes, err
        }
    }
    request, err := http.NewRequest("DELETE", url, bytes.NewBuffer(bodyJson))
    if err != nil {
        log.Println(err)
        return resultBytes, err
    }
    request.Header.Set("Content-type", contentType)
    // add headers
    if headers != nil {
        for key, val := range headers {
            request.Header.Add(key, val)
        }
    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        return resultBytes, err
    }
    defer resp.Body.Close()
    resultBytes, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return resultBytes, err
    }
    return resultBytes, nil
}