feat(数据库): 增强数据库集成功能并改进空值处理

- 在storageConfig.go中添加数据库启用状态同步逻辑
- 修改Camera结构体字段为sql.Null类型以更好处理数据库空值
- 新增DatabaseGetCameras和DatabaseGetCamera方法用于摄像头查询
- 在apiHTTPCamera.go中添加空值处理辅助函数
- 重构Java集成API以使用新的数据库结构和空值处理
- 更新config.json中的数据库凭证
ziyun-rtsp-web
karlkyo 8 months ago
parent 6a473d0732
commit 1a617370d6

@ -1,6 +1,7 @@
package main package main
import ( import (
"database/sql"
"fmt" "fmt"
"net/http" "net/http"
"time" "time"
@ -9,6 +10,30 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// getStringValue 获取sql.NullString的值
func getStringValue(ns sql.NullString) string {
if ns.Valid {
return ns.String
}
return ""
}
// getInt64Value 获取sql.NullInt64的值
func getInt64Value(ni sql.NullInt64) int64 {
if ni.Valid {
return ni.Int64
}
return 0
}
// getTimeValue 获取sql.NullTime的值
func getTimeValue(nt sql.NullTime) time.Time {
if nt.Valid {
return nt.Time
}
return time.Time{}
}
// CameraRequest 摄像头请求结构 // CameraRequest 摄像头请求结构
type CameraRequest struct { type CameraRequest struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
@ -82,23 +107,23 @@ func HTTPAPIServerCameras(c *gin.Context) {
CameraID: camera.CameraID, CameraID: camera.CameraID,
IP: camera.IP, IP: camera.IP,
Port: camera.Port, Port: camera.Port,
Username: camera.Username, Username: getStringValue(camera.Username),
Password: camera.Password, Password: getStringValue(camera.Password),
URL: camera.URL, URL: camera.URL,
CameraProduce: camera.CameraProduce, CameraProduce: getStringValue(camera.CameraProduce),
CameraName: camera.CameraName, CameraName: getStringValue(camera.CameraName),
DeviceType: camera.DeviceType, DeviceType: getStringValue(camera.DeviceType),
UnitCode: camera.UnitCode, UnitCode: getStringValue(camera.UnitCode),
NvrProduce: camera.NvrProduce, NvrProduce: getStringValue(camera.NvrProduce),
NvrPath: camera.NvrPath, NvrPath: getStringValue(camera.NvrPath),
PlayBack: camera.PlayBack, PlayBack: getStringValue(camera.PlayBack),
DelFlag: camera.DelFlag, DelFlag: camera.DelFlag,
CreateBy: camera.CreateBy, CreateBy: getStringValue(camera.CreateBy),
CreateTime: camera.CreateTime, CreateTime: getTimeValue(camera.CreateTime),
UpdateBy: camera.UpdateBy, UpdateBy: getStringValue(camera.UpdateBy),
UpdateTime: camera.UpdateTime, UpdateTime: getTimeValue(camera.UpdateTime),
UserID: camera.UserID, UserID: getInt64Value(camera.UserID),
DeptID: camera.DeptID, DeptID: getInt64Value(camera.DeptID),
StreamStatus: streamStatus, StreamStatus: streamStatus,
} }
responses = append(responses, response) responses = append(responses, response)
@ -156,23 +181,23 @@ func HTTPAPIServerCamerasByUnitCode(c *gin.Context) {
CameraID: camera.CameraID, CameraID: camera.CameraID,
IP: camera.IP, IP: camera.IP,
Port: camera.Port, Port: camera.Port,
Username: camera.Username, Username: getStringValue(camera.Username),
Password: camera.Password, Password: getStringValue(camera.Password),
URL: camera.URL, URL: camera.URL,
CameraProduce: camera.CameraProduce, CameraProduce: getStringValue(camera.CameraProduce),
CameraName: camera.CameraName, CameraName: getStringValue(camera.CameraName),
DeviceType: camera.DeviceType, DeviceType: getStringValue(camera.DeviceType),
UnitCode: camera.UnitCode, UnitCode: getStringValue(camera.UnitCode),
NvrProduce: camera.NvrProduce, NvrProduce: getStringValue(camera.NvrProduce),
NvrPath: camera.NvrPath, NvrPath: getStringValue(camera.NvrPath),
PlayBack: camera.PlayBack, PlayBack: getStringValue(camera.PlayBack),
DelFlag: camera.DelFlag, DelFlag: camera.DelFlag,
CreateBy: camera.CreateBy, CreateBy: getStringValue(camera.CreateBy),
CreateTime: camera.CreateTime, CreateTime: getTimeValue(camera.CreateTime),
UpdateBy: camera.UpdateBy, UpdateBy: getStringValue(camera.UpdateBy),
UpdateTime: camera.UpdateTime, UpdateTime: getTimeValue(camera.UpdateTime),
UserID: camera.UserID, UserID: getInt64Value(camera.UserID),
DeptID: camera.DeptID, DeptID: getInt64Value(camera.DeptID),
StreamStatus: streamStatus, StreamStatus: streamStatus,
} }
responses = append(responses, response) responses = append(responses, response)
@ -206,19 +231,19 @@ func HTTPAPIServerCameraAdd(c *gin.Context) {
camera := Camera{ camera := Camera{
IP: req.IP, IP: req.IP,
Port: 554, // 默认RTSP端口 Port: 554, // 默认RTSP端口
Username: req.Username, Username: sql.NullString{String: req.Username, Valid: req.Username != ""},
Password: req.Password, Password: sql.NullString{String: req.Password, Valid: req.Password != ""},
URL: req.RTSPURL, URL: req.RTSPURL,
CameraName: req.Name, CameraName: sql.NullString{String: req.Name, Valid: true},
DeviceType: "网络摄像头", DeviceType: sql.NullString{String: "网络摄像头", Valid: true},
UnitCode: "DEFAULT", // 默认单位代码 UnitCode: sql.NullString{String: "DEFAULT", Valid: true}, // 默认单位代码
DelFlag: "0", DelFlag: "0",
CreateBy: "admin", CreateBy: sql.NullString{String: "admin", Valid: true},
CreateTime: time.Now(), CreateTime: sql.NullTime{Time: time.Now(), Valid: true},
UpdateBy: "admin", UpdateBy: sql.NullString{String: "admin", Valid: true},
UpdateTime: time.Now(), UpdateTime: sql.NullTime{Time: time.Now(), Valid: true},
UserID: 1, UserID: sql.NullInt64{Int64: 1, Valid: true},
DeptID: 1, DeptID: sql.NullInt64{Int64: 1, Valid: true},
} }
// 保存到数据库 // 保存到数据库
@ -314,12 +339,12 @@ func HTTPAPIServerCameraUpdate(c *gin.Context) {
// 更新摄像头信息 - 适配qsc_camera表 // 更新摄像头信息 - 适配qsc_camera表
updatedCamera := *existingCamera // 复制现有摄像头信息 updatedCamera := *existingCamera // 复制现有摄像头信息
updatedCamera.IP = req.IP updatedCamera.IP = req.IP
updatedCamera.Username = req.Username updatedCamera.Username = sql.NullString{String: req.Username, Valid: req.Username != ""}
updatedCamera.Password = req.Password updatedCamera.Password = sql.NullString{String: req.Password, Valid: req.Password != ""}
updatedCamera.URL = req.RTSPURL updatedCamera.URL = req.RTSPURL
updatedCamera.CameraName = req.Name updatedCamera.CameraName = sql.NullString{String: req.Name, Valid: true}
updatedCamera.UpdateBy = "admin" updatedCamera.UpdateBy = sql.NullString{String: "admin", Valid: true}
updatedCamera.UpdateTime = time.Now() updatedCamera.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true}
// 更新数据库 // 更新数据库
err = Storage.dbManager.UpdateCamera(&updatedCamera) err = Storage.dbManager.UpdateCamera(&updatedCamera)
@ -465,19 +490,19 @@ func HTTPAPIServerCameraGet(c *gin.Context) {
response := CameraResponse{ response := CameraResponse{
CameraID: camera.CameraID, CameraID: camera.CameraID,
CameraName: camera.CameraName, CameraName: getStringValue(camera.CameraName),
IP: camera.IP, IP: camera.IP,
Port: camera.Port, Port: camera.Port,
Username: camera.Username, Username: getStringValue(camera.Username),
// Password: camera.Password, // 不返回密码 // Password: camera.Password, // 不返回密码
URL: camera.URL, URL: camera.URL,
CameraProduce: camera.CameraProduce, CameraProduce: getStringValue(camera.CameraProduce),
DeviceType: camera.DeviceType, DeviceType: getStringValue(camera.DeviceType),
UnitCode: camera.UnitCode, UnitCode: getStringValue(camera.UnitCode),
NvrProduce: camera.NvrProduce, NvrProduce: getStringValue(camera.NvrProduce),
StreamStatus: status, StreamStatus: status,
CreateTime: camera.CreateTime, CreateTime: getTimeValue(camera.CreateTime),
UpdateTime: camera.UpdateTime, UpdateTime: getTimeValue(camera.UpdateTime),
} }
c.JSON(http.StatusOK, response) c.JSON(http.StatusOK, response)

@ -1,7 +1,6 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
@ -30,22 +29,22 @@ type StreamListResponse struct {
Streams []Stream `json:"streams"` Streams []Stream `json:"streams"`
} }
// Camera 摄像头信息结构 // JavaCamera 摄像头信息结构 - 用于Java集成API
type Camera struct { type JavaCamera struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
IP string `json:"ip"` IP string `json:"ip"`
Port int `json:"port"` Port int `json:"port"`
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password,omitempty"` // 敏感信息可选返回 Password string `json:"password,omitempty"` // 敏感信息可选返回
RTSPURL string `json:"rtsp_url"` RTSPURL string `json:"rtsp_url"`
Status string `json:"status"` Status string `json:"status"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
DeviceType string `json:"device_type"` DeviceType string `json:"device_type"`
UnitCode string `json:"unit_code"` UnitCode string `json:"unit_code"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
PlayURLs PlayURLs `json:"play_urls"` PlayURLs PlayURLs `json:"play_urls"`
} }
// Stream 流信息结构 // Stream 流信息结构
@ -81,11 +80,11 @@ func HTTPJavaAPICameras(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20")) size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
var cameras []Camera var cameras []JavaCamera
var total int var total int
// 如果数据库启用,从数据库获取 // 如果数据库启用,从数据库获取
if Storage.ServerDatabaseEnabled() { if Storage.Server.DatabaseEnabled {
dbCameras, err := Storage.DatabaseGetCameras() dbCameras, err := Storage.DatabaseGetCameras()
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, JavaAPIResponse{ c.JSON(http.StatusInternalServerError, JavaAPIResponse{
@ -98,20 +97,20 @@ func HTTPJavaAPICameras(c *gin.Context) {
// 转换数据库摄像头为API格式 // 转换数据库摄像头为API格式
for _, dbCamera := range dbCameras { for _, dbCamera := range dbCameras {
camera := Camera{ camera := JavaCamera{
ID: dbCamera.ID, ID: fmt.Sprintf("%d", dbCamera.CameraID),
Name: dbCamera.Name, Name: getStringValue(dbCamera.CameraName),
IP: dbCamera.IP, IP: dbCamera.IP,
Port: dbCamera.Port, Port: dbCamera.Port,
Username: dbCamera.Username, Username: getStringValue(dbCamera.Username),
RTSPURL: dbCamera.RTSPURL, RTSPURL: dbCamera.URL,
Status: dbCamera.Status, Status: "online", // 默认状态
Enabled: dbCamera.Enabled, Enabled: dbCamera.DelFlag == "0", // 删除标志为0表示启用
DeviceType: dbCamera.DeviceType, DeviceType: getStringValue(dbCamera.DeviceType),
UnitCode: dbCamera.UnitCode, UnitCode: getStringValue(dbCamera.UnitCode),
CreatedAt: dbCamera.CreatedAt, CreatedAt: getTimeValue(dbCamera.CreateTime),
UpdatedAt: dbCamera.UpdatedAt, UpdatedAt: getTimeValue(dbCamera.UpdateTime),
PlayURLs: generatePlayURLs(dbCamera.ID), PlayURLs: generatePlayURLs(fmt.Sprintf("%d", dbCamera.CameraID)),
} }
// 过滤条件 // 过滤条件
@ -126,9 +125,9 @@ func HTTPJavaAPICameras(c *gin.Context) {
} }
} else { } else {
// 从流配置获取 // 从流配置获取
streamsList := Storage.StreamsList() streamsList := Storage.Streams
for streamID := range streamsList { for streamID := range streamsList {
camera := Camera{ camera := JavaCamera{
ID: streamID, ID: streamID,
Name: fmt.Sprintf("Stream %s", streamID), Name: fmt.Sprintf("Stream %s", streamID),
Status: "online", Status: "online",
@ -145,7 +144,7 @@ func HTTPJavaAPICameras(c *gin.Context) {
start := (page - 1) * size start := (page - 1) * size
end := start + size end := start + size
if start > total { if start > total {
cameras = []Camera{} cameras = []JavaCamera{}
} else if end > total { } else if end > total {
cameras = cameras[start:] cameras = cameras[start:]
} else { } else {
@ -156,9 +155,9 @@ func HTTPJavaAPICameras(c *gin.Context) {
Code: 200, Code: 200,
Message: "Success", Message: "Success",
Success: true, Success: true,
Data: CameraListResponse{ Data: map[string]interface{}{
Total: total, "total": total,
Cameras: cameras, "cameras": cameras,
}, },
} }
@ -179,7 +178,7 @@ func HTTPJavaAPIStreams(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20")) size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
streamsList := Storage.StreamsList() streamsList := Storage.Streams
var streams []Stream var streams []Stream
for streamID, streamData := range streamsList { for streamID, streamData := range streamsList {
@ -191,7 +190,7 @@ func HTTPJavaAPIStreams(c *gin.Context) {
} }
// 获取通道信息 // 获取通道信息
if streamData != nil { if len(streamData.Channels) > 0 {
for channelID := range streamData.Channels { for channelID := range streamData.Channels {
stream.Channels[channelID] = fmt.Sprintf("Channel %s", channelID) stream.Channels[channelID] = fmt.Sprintf("Channel %s", channelID)
} }
@ -238,7 +237,7 @@ func HTTPJavaAPICameraDetail(c *gin.Context) {
return return
} }
if Storage.ServerDatabaseEnabled() { if Storage.Server.DatabaseEnabled {
camera, err := Storage.DatabaseGetCamera(cameraID) camera, err := Storage.DatabaseGetCamera(cameraID)
if err != nil { if err != nil {
c.JSON(http.StatusNotFound, JavaAPIResponse{ c.JSON(http.StatusNotFound, JavaAPIResponse{
@ -249,20 +248,20 @@ func HTTPJavaAPICameraDetail(c *gin.Context) {
return return
} }
apiCamera := Camera{ apiCamera := JavaCamera{
ID: camera.ID, ID: fmt.Sprintf("%d", camera.CameraID),
Name: camera.Name, Name: getStringValue(camera.CameraName),
IP: camera.IP, IP: camera.IP,
Port: camera.Port, Port: camera.Port,
Username: camera.Username, Username: getStringValue(camera.Username),
RTSPURL: camera.RTSPURL, RTSPURL: camera.URL,
Status: camera.Status, Status: "online",
Enabled: camera.Enabled, Enabled: camera.DelFlag == "0",
DeviceType: camera.DeviceType, DeviceType: getStringValue(camera.DeviceType),
UnitCode: camera.UnitCode, UnitCode: getStringValue(camera.UnitCode),
CreatedAt: camera.CreatedAt, CreatedAt: getTimeValue(camera.CreateTime),
UpdatedAt: camera.UpdatedAt, UpdatedAt: getTimeValue(camera.UpdateTime),
PlayURLs: generatePlayURLs(camera.ID), PlayURLs: generatePlayURLs(fmt.Sprintf("%d", camera.CameraID)),
} }
c.JSON(http.StatusOK, JavaAPIResponse{ c.JSON(http.StatusOK, JavaAPIResponse{
@ -282,7 +281,7 @@ func HTTPJavaAPICameraDetail(c *gin.Context) {
return return
} }
camera := Camera{ camera := JavaCamera{
ID: cameraID, ID: cameraID,
Name: fmt.Sprintf("Stream %s", cameraID), Name: fmt.Sprintf("Stream %s", cameraID),
Status: "online", Status: "online",
@ -303,19 +302,19 @@ func HTTPJavaAPICameraDetail(c *gin.Context) {
func HTTPJavaAPISystemInfo(c *gin.Context) { func HTTPJavaAPISystemInfo(c *gin.Context) {
systemInfo := map[string]interface{}{ systemInfo := map[string]interface{}{
"version": "1.0.0", "version": "1.0.0",
"database_enabled": Storage.ServerDatabaseEnabled(), "database_enabled": Storage.Server.DatabaseEnabled,
"demo_enabled": Storage.ServerHTTPDemo(), "demo_enabled": Storage.ServerHTTPDemo(),
"total_streams": len(Storage.StreamsList()), "total_streams": len(Storage.Streams),
"server_time": time.Now().Format(time.RFC3339), "server_time": time.Now().Format(time.RFC3339),
} }
if Storage.ServerDatabaseEnabled() { if Storage.Server.DatabaseEnabled {
cameras, err := Storage.DatabaseGetCameras() cameras, err := Storage.DatabaseGetCameras()
if err == nil { if err == nil {
systemInfo["total_cameras"] = len(cameras) systemInfo["total_cameras"] = len(cameras)
onlineCount := 0 onlineCount := 0
for _, camera := range cameras { for _, camera := range cameras {
if camera.Status == "online" { if camera.DelFlag == "0" { // 删除标志为0表示在线
onlineCount++ onlineCount++
} }
} }

@ -29,8 +29,8 @@
"type": "mysql", "type": "mysql",
"host": "47.96.78.103", "host": "47.96.78.103",
"port": 6330, "port": 6330,
"username": "root", "username": "JgzY",
"password": "Jgzy@#%6330^awSl", "password": "JgzY@^&-)XswL",
"database": "ziyun", "database": "ziyun",
"table_name": "qsc_camera" "table_name": "qsc_camera"
} }

@ -24,26 +24,26 @@ type DatabaseConfig struct {
// Camera 摄像头数据库模型 - 适配qsc_camera表 // Camera 摄像头数据库模型 - 适配qsc_camera表
type Camera struct { type Camera struct {
CameraID int `json:"camera_id" db:"camera_id"` CameraID int `json:"camera_id" db:"camera_id"`
IP string `json:"ip" db:"ip"` IP string `json:"ip" db:"ip"`
Port int `json:"port" db:"port"` Port int `json:"port" db:"port"`
Username string `json:"username" db:"username"` Username sql.NullString `json:"username" db:"username"`
Password string `json:"password" db:"password"` Password sql.NullString `json:"password" db:"password"`
URL string `json:"url" db:"url"` URL string `json:"url" db:"url"`
CameraProduce string `json:"camera_produce" db:"camera_produce"` CameraProduce sql.NullString `json:"camera_produce" db:"camera_produce"`
CameraName string `json:"camera_name" db:"camera_name"` CameraName sql.NullString `json:"camera_name" db:"camera_name"`
DeviceType string `json:"device_type" db:"device_type"` DeviceType sql.NullString `json:"device_type" db:"device_type"`
UnitCode string `json:"unit_code" db:"unit_code"` UnitCode sql.NullString `json:"unit_code" db:"unit_code"`
NvrProduce string `json:"nvr_produce" db:"nvr_produce"` NvrProduce sql.NullString `json:"nvr_produce" db:"nvr_produce"`
NvrPath string `json:"nvr_path" db:"nvr_path"` NvrPath sql.NullString `json:"nvr_path" db:"nvr_path"`
PlayBack string `json:"play_back" db:"play_back"` PlayBack sql.NullString `json:"play_back" db:"play_back"`
DelFlag string `json:"del_flag" db:"del_flag"` DelFlag string `json:"del_flag" db:"del_flag"`
CreateBy string `json:"create_by" db:"create_by"` CreateBy sql.NullString `json:"create_by" db:"create_by"`
CreateTime time.Time `json:"create_time" db:"create_time"` CreateTime sql.NullTime `json:"create_time" db:"create_time"`
UpdateBy string `json:"update_by" db:"update_by"` UpdateBy sql.NullString `json:"update_by" db:"update_by"`
UpdateTime time.Time `json:"update_time" db:"update_time"` UpdateTime sql.NullTime `json:"update_time" db:"update_time"`
UserID int64 `json:"user_id" db:"user_id"` UserID sql.NullInt64 `json:"user_id" db:"user_id"`
DeptID int64 `json:"dept_id" db:"dept_id"` DeptID sql.NullInt64 `json:"dept_id" db:"dept_id"`
} }
// DatabaseManager 数据库管理器 // DatabaseManager 数据库管理器
@ -233,8 +233,8 @@ func (dm *DatabaseManager) GetCameraByID(id string) (*Camera, error) {
// CreateCamera 创建摄像头 - 适配qsc_camera表 // CreateCamera 创建摄像头 - 适配qsc_camera表
func (dm *DatabaseManager) CreateCamera(camera *Camera) error { func (dm *DatabaseManager) CreateCamera(camera *Camera) error {
camera.CreateTime = time.Now() camera.CreateTime = sql.NullTime{Time: time.Now(), Valid: true}
camera.UpdateTime = time.Now() camera.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true}
query := `INSERT INTO qsc_camera (ip, port, username, password, url, camera_produce, query := `INSERT INTO qsc_camera (ip, port, username, password, url, camera_produce,
camera_name, device_type, unit_code, nvr_produce, nvr_path, play_back, camera_name, device_type, unit_code, nvr_produce, nvr_path, play_back,
@ -252,7 +252,7 @@ func (dm *DatabaseManager) CreateCamera(camera *Camera) error {
// UpdateCamera 更新摄像头 - 适配qsc_camera表 // UpdateCamera 更新摄像头 - 适配qsc_camera表
func (dm *DatabaseManager) UpdateCamera(camera *Camera) error { func (dm *DatabaseManager) UpdateCamera(camera *Camera) error {
camera.UpdateTime = time.Now() camera.UpdateTime = sql.NullTime{Time: time.Now(), Valid: true}
query := `UPDATE qsc_camera SET ip=?, port=?, username=?, password=?, url=?, query := `UPDATE qsc_camera SET ip=?, port=?, username=?, password=?, url=?,
camera_produce=?, camera_name=?, device_type=?, unit_code=?, nvr_produce=?, camera_produce=?, camera_name=?, device_type=?, unit_code=?, nvr_produce=?,
@ -287,19 +287,24 @@ func CameraToStream(camera Camera) StreamST {
rtspURL := camera.URL rtspURL := camera.URL
if rtspURL == "" { if rtspURL == "" {
// 如果URL为空根据IP、端口、用户名密码构建RTSP URL // 如果URL为空根据IP、端口、用户名密码构建RTSP URL
if camera.Username != "" && camera.Password != "" { if camera.Username.Valid && camera.Password.Valid && camera.Username.String != "" && camera.Password.String != "" {
rtspURL = fmt.Sprintf("rtsp://%s:%s@%s:%d/stream1", rtspURL = fmt.Sprintf("rtsp://%s:%s@%s:%d/stream1",
camera.Username, camera.Password, camera.IP, camera.Port) camera.Username.String, camera.Password.String, camera.IP, camera.Port)
} else { } else {
rtspURL = fmt.Sprintf("rtsp://%s:%d/stream1", camera.IP, camera.Port) rtspURL = fmt.Sprintf("rtsp://%s:%d/stream1", camera.IP, camera.Port)
} }
} }
cameraName := "Unknown Camera"
if camera.CameraName.Valid {
cameraName = camera.CameraName.String
}
return StreamST{ return StreamST{
Name: camera.CameraName, Name: cameraName,
Channels: map[string]ChannelST{ Channels: map[string]ChannelST{
"0": { "0": {
Name: camera.CameraName, Name: cameraName,
URL: rtspURL, URL: rtspURL,
OnDemand: false, // 根据需要设置 OnDemand: false, // 根据需要设置
Debug: false, // 根据需要设置 Debug: false, // 根据需要设置
@ -315,21 +320,21 @@ func StreamToCamera(id string, stream StreamST) Camera {
cameraID, _ := strconv.Atoi(id) cameraID, _ := strconv.Atoi(id)
camera := Camera{ camera := Camera{
CameraID: cameraID, CameraID: cameraID,
CameraName: stream.Name, CameraName: sql.NullString{String: stream.Name, Valid: true},
IP: "", // 从URL中解析 IP: "", // 从URL中解析
Port: 554, // 默认RTSP端口 Port: 554, // 默认RTSP端口
Username: "", // 从URL中解析 Username: sql.NullString{String: "", Valid: false}, // 从URL中解析
Password: "", // 从URL中解析 Password: sql.NullString{String: "", Valid: false}, // 从URL中解析
URL: "", // 将从第一个通道获取 URL: "", // 将从第一个通道获取
DeviceType: "网络摄像头", DeviceType: sql.NullString{String: "网络摄像头", Valid: true},
UnitCode: "DEFAULT", UnitCode: sql.NullString{String: "DEFAULT", Valid: true},
DelFlag: "0", DelFlag: "0",
CreateBy: "system", CreateBy: sql.NullString{String: "system", Valid: true},
CreateTime: time.Now(), CreateTime: sql.NullTime{Time: time.Now(), Valid: true},
UpdateBy: "system", UpdateBy: sql.NullString{String: "system", Valid: true},
UpdateTime: time.Now(), UpdateTime: sql.NullTime{Time: time.Now(), Valid: true},
UserID: 1, UserID: sql.NullInt64{Int64: 1, Valid: true},
DeptID: 1, DeptID: sql.NullInt64{Int64: 1, Valid: true},
} }
// 获取第一个通道的配置 // 获取第一个通道的配置

@ -47,6 +47,11 @@ func NewStreamCore() *StorageST {
} }
debug = tmp.Server.Debug debug = tmp.Server.Debug
// 同步数据库启用状态
if tmp.Server.DatabaseEnabled {
tmp.Database.Enabled = true
}
// 初始化数据库连接 // 初始化数据库连接
if tmp.Database.Enabled { if tmp.Database.Enabled {
err = tmp.InitDatabase() err = tmp.InitDatabase()

@ -219,6 +219,38 @@ func (obj *StorageST) GetDatabaseStatus() map[string]interface{} {
return status return status
} }
// DatabaseGetCameras 获取所有摄像头
func (obj *StorageST) DatabaseGetCameras() ([]Camera, error) {
obj.mutex.RLock()
defer obj.mutex.RUnlock()
if obj.dbManager == nil {
return nil, fmt.Errorf("database manager not initialized")
}
return obj.dbManager.GetAllCameras()
}
// DatabaseGetCamera 根据ID获取摄像头
func (obj *StorageST) DatabaseGetCamera(id string) (*Camera, error) {
obj.mutex.RLock()
defer obj.mutex.RUnlock()
if obj.dbManager == nil {
return nil, fmt.Errorf("database manager not initialized")
}
return obj.dbManager.GetCameraByID(id)
}
// StreamExist 检查流是否存在
func (obj *StorageST) StreamExist(uuid string) bool {
obj.mutex.RLock()
defer obj.mutex.RUnlock()
_, ok := obj.Streams[uuid]
return ok
}
// CloseDatabase 关闭数据库连接 // CloseDatabase 关闭数据库连接
func (obj *StorageST) CloseDatabase() error { func (obj *StorageST) CloseDatabase() error {
obj.mutex.Lock() obj.mutex.Lock()

Loading…
Cancel
Save