You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RTSPtoWeb/apiHTTPCamera.go

416 lines
9.3 KiB
Go

package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
)
// CameraRequest 摄像头请求结构
type CameraRequest struct {
Name string `json:"name" binding:"required"`
IP string `json:"ip" binding:"required"`
Username string `json:"username"`
Password string `json:"password"`
RTSPURL string `json:"rtsp_url" binding:"required"`
Enabled bool `json:"enabled"`
}
// CameraResponse 摄像头响应结构
type CameraResponse struct {
ID string `json:"id"`
Name string `json:"name"`
IP string `json:"ip"`
Username string `json:"username"`
Password string `json:"password,omitempty"` // 密码在响应中可选
RTSPURL string `json:"rtsp_url"`
Enabled bool `json:"enabled"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// HTTPAPIServerCameras 获取所有摄像头列表
func HTTPAPIServerCameras(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
if Storage.dbManager == nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Database manager not initialized",
})
return
}
cameras, err := Storage.dbManager.GetAllCameras()
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameras",
"call": "GetAllCameras",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
// 转换为响应格式
var response []CameraResponse
for _, camera := range cameras {
status := "offline"
if stream, exists := Storage.Streams[camera.ID]; exists {
if len(stream.Channels) > 0 {
for _, channel := range stream.Channels {
if channel.runLock {
status = "online"
break
}
}
}
}
response = append(response, CameraResponse{
ID: camera.ID,
Name: camera.Name,
IP: camera.IP,
Username: camera.Username,
// Password: camera.Password, // 不返回密码
RTSPURL: camera.RTSPURL,
Enabled: camera.Enabled,
Status: status,
CreatedAt: camera.CreatedAt,
UpdatedAt: camera.UpdatedAt,
})
}
c.JSON(http.StatusOK, gin.H{
"cameras": response,
"count": len(response),
})
}
// HTTPAPIServerCameraAdd 添加新摄像头
func HTTPAPIServerCameraAdd(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
var req CameraRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
// 生成新的UUID
cameraID := uuid.New().String()
// 创建摄像头记录
camera := Camera{
ID: cameraID,
Name: req.Name,
IP: req.IP,
Username: req.Username,
Password: req.Password,
RTSPURL: req.RTSPURL,
Enabled: req.Enabled,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
// 保存到数据库
err := Storage.dbManager.CreateCamera(&camera)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraAdd",
"call": "CreateCamera",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
// 转换为流配置并添加到内存
stream := CameraToStream(camera)
err = Storage.StreamAdd(cameraID, stream)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraAdd",
"call": "StreamAdd",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusCreated, gin.H{
"message": "Camera added successfully",
"camera_id": cameraID,
})
}
// HTTPAPIServerCameraUpdate 更新摄像头
func HTTPAPIServerCameraUpdate(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
cameraID := c.Param("uuid")
if cameraID == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Camera ID is required",
})
return
}
var req CameraRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
// 检查摄像头是否存在
existingCamera, err := Storage.dbManager.GetCameraByID(cameraID)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraUpdate",
"call": "GetCameraByID",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
if existingCamera == nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Camera not found",
})
return
}
// 更新摄像头信息
updatedCamera := Camera{
ID: cameraID,
Name: req.Name,
IP: req.IP,
Username: req.Username,
Password: req.Password,
RTSPURL: req.RTSPURL,
Enabled: req.Enabled,
CreatedAt: existingCamera.CreatedAt,
UpdatedAt: time.Now(),
}
// 更新数据库
err = Storage.dbManager.UpdateCamera(&updatedCamera)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraUpdate",
"call": "UpdateCamera",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
// 更新内存中的流配置
stream := CameraToStream(updatedCamera)
err = Storage.StreamEdit(cameraID, stream)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraUpdate",
"call": "StreamEdit",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "Camera updated successfully",
})
}
// HTTPAPIServerCameraDelete 删除摄像头
func HTTPAPIServerCameraDelete(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
cameraID := c.Param("uuid")
if cameraID == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Camera ID is required",
})
return
}
// 检查摄像头是否存在
existingCamera, err := Storage.dbManager.GetCameraByID(cameraID)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraDelete",
"call": "GetCameraByID",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
if existingCamera == nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Camera not found",
})
return
}
// 从内存中删除流
err = Storage.StreamDelete(cameraID)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraDelete",
"call": "StreamDelete",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "Camera deleted successfully",
})
}
// HTTPAPIServerCameraGet 获取单个摄像头信息
func HTTPAPIServerCameraGet(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
cameraID := c.Param("uuid")
if cameraID == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Camera ID is required",
})
return
}
camera, err := Storage.dbManager.GetCameraByID(cameraID)
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraGet",
"call": "GetCameraByID",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
if camera == nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "Camera not found",
})
return
}
// 检查流状态
status := "offline"
if stream, exists := Storage.Streams[camera.ID]; exists {
if len(stream.Channels) > 0 {
for _, channel := range stream.Channels {
if channel.runLock {
status = "online"
break
}
}
}
}
response := CameraResponse{
ID: camera.ID,
Name: camera.Name,
IP: camera.IP,
Username: camera.Username,
// Password: camera.Password, // 不返回密码
RTSPURL: camera.RTSPURL,
Enabled: camera.Enabled,
Status: status,
CreatedAt: camera.CreatedAt,
UpdatedAt: camera.UpdatedAt,
}
c.JSON(http.StatusOK, response)
}
// HTTPAPIServerCameraRefresh 刷新摄像头列表(从数据库重新加载)
func HTTPAPIServerCameraRefresh(c *gin.Context) {
if !Storage.Server.DatabaseEnabled {
c.JSON(http.StatusServiceUnavailable, gin.H{
"error": "Database is not enabled",
})
return
}
err := Storage.RefreshStreamsFromDatabase()
if err != nil {
log.WithFields(logrus.Fields{
"module": "api",
"func": "HTTPAPIServerCameraRefresh",
"call": "RefreshStreamsFromDatabase",
}).Errorln(err.Error())
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "Cameras refreshed successfully",
})
}
// HTTPAPIServerDatabaseStatus 获取数据库状态
func HTTPAPIServerDatabaseStatus(c *gin.Context) {
status := Storage.GetDatabaseStatus()
c.JSON(http.StatusOK, status)
}