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/apiHTTPJavaIntegration.go

343 lines
8.5 KiB
Go

package main
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
)
// JavaAPIResponse 标准化的Java API响应格式
type JavaAPIResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
Success bool `json:"success"`
}
// CameraListResponse 摄像头列表响应
type CameraListResponse struct {
Total int `json:"total"`
Cameras []Camera `json:"cameras"`
}
// StreamListResponse 流列表响应
type StreamListResponse struct {
Total int `json:"total"`
Streams []Stream `json:"streams"`
}
// JavaCamera 摄像头信息结构 - 用于Java集成API
type JavaCamera struct {
ID string `json:"id"`
Name string `json:"name"`
IP string `json:"ip"`
Port int `json:"port"`
Username string `json:"username"`
Password string `json:"password,omitempty"` // 敏感信息可选返回
RTSPURL string `json:"rtsp_url"`
Status string `json:"status"`
Enabled bool `json:"enabled"`
DeviceType string `json:"device_type"`
UnitCode string `json:"unit_code"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
PlayURLs PlayURLs `json:"play_urls"`
}
// Stream 流信息结构
type Stream struct {
ID string `json:"id"`
Name string `json:"name"`
Channels map[string]string `json:"channels"`
PlayURLs PlayURLs `json:"play_urls"`
}
// PlayURLs 播放地址结构
type PlayURLs struct {
HLS string `json:"hls"`
WebRTC string `json:"webrtc"`
MSE string `json:"mse"`
All string `json:"all"`
}
// HTTPJavaAPICameras Java项目专用的摄像头列表API
func HTTPJavaAPICameras(c *gin.Context) {
if !Storage.ServerHTTPDemo() {
c.JSON(http.StatusForbidden, JavaAPIResponse{
Code: 403,
Message: "Demo mode is disabled",
Success: false,
})
return
}
// 获取查询参数
unitCode := c.Query("unit_code")
status := c.Query("status")
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
var cameras []JavaCamera
var total int
// 如果数据库启用,从数据库获取
if Storage.Server.DatabaseEnabled {
dbCameras, err := Storage.DatabaseGetCameras()
if err != nil {
c.JSON(http.StatusInternalServerError, JavaAPIResponse{
Code: 500,
Message: fmt.Sprintf("Database error: %v", err),
Success: false,
})
return
}
// 转换数据库摄像头为API格式
for _, dbCamera := range dbCameras {
camera := JavaCamera{
ID: fmt.Sprintf("%d", dbCamera.CameraID),
Name: getStringValue(dbCamera.CameraName),
IP: dbCamera.IP,
Port: dbCamera.Port,
Username: getStringValue(dbCamera.Username),
RTSPURL: dbCamera.URL,
Status: "online", // 默认状态
Enabled: dbCamera.DelFlag == "0", // 删除标志为0表示启用
DeviceType: getStringValue(dbCamera.DeviceType),
UnitCode: getStringValue(dbCamera.UnitCode),
CreatedAt: getTimeValue(dbCamera.CreateTime),
UpdatedAt: getTimeValue(dbCamera.UpdateTime),
PlayURLs: generatePlayURLs(fmt.Sprintf("%d", dbCamera.CameraID)),
}
// 过滤条件
if unitCode != "" && camera.UnitCode != unitCode {
continue
}
if status != "" && camera.Status != status {
continue
}
cameras = append(cameras, camera)
}
} else {
// 从流配置获取
streamsList := Storage.Streams
for streamID := range streamsList {
camera := JavaCamera{
ID: streamID,
Name: fmt.Sprintf("Stream %s", streamID),
Status: "online",
Enabled: true,
PlayURLs: generatePlayURLs(streamID),
}
cameras = append(cameras, camera)
}
}
total = len(cameras)
// 分页处理
start := (page - 1) * size
end := start + size
if start > total {
cameras = []JavaCamera{}
} else if end > total {
cameras = cameras[start:]
} else {
cameras = cameras[start:end]
}
response := JavaAPIResponse{
Code: 200,
Message: "Success",
Success: true,
Data: map[string]interface{}{
"total": total,
"cameras": cameras,
},
}
c.JSON(http.StatusOK, response)
}
// HTTPJavaAPIStreams Java项目专用的流列表API
func HTTPJavaAPIStreams(c *gin.Context) {
if !Storage.ServerHTTPDemo() {
c.JSON(http.StatusForbidden, JavaAPIResponse{
Code: 403,
Message: "Demo mode is disabled",
Success: false,
})
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
streamsList := Storage.Streams
var streams []Stream
for streamID, streamData := range streamsList {
stream := Stream{
ID: streamID,
Name: fmt.Sprintf("Stream %s", streamID),
Channels: make(map[string]string),
PlayURLs: generatePlayURLs(streamID),
}
// 获取通道信息
if len(streamData.Channels) > 0 {
for channelID := range streamData.Channels {
stream.Channels[channelID] = fmt.Sprintf("Channel %s", channelID)
}
}
streams = append(streams, stream)
}
total := len(streams)
// 分页处理
start := (page - 1) * size
end := start + size
if start > total {
streams = []Stream{}
} else if end > total {
streams = streams[start:]
} else {
streams = streams[start:end]
}
response := JavaAPIResponse{
Code: 200,
Message: "Success",
Success: true,
Data: StreamListResponse{
Total: total,
Streams: streams,
},
}
c.JSON(http.StatusOK, response)
}
// HTTPJavaAPICameraDetail 获取摄像头详情
func HTTPJavaAPICameraDetail(c *gin.Context) {
cameraID := c.Param("id")
if cameraID == "" {
c.JSON(http.StatusBadRequest, JavaAPIResponse{
Code: 400,
Message: "Camera ID is required",
Success: false,
})
return
}
if Storage.Server.DatabaseEnabled {
camera, err := Storage.DatabaseGetCamera(cameraID)
if err != nil {
c.JSON(http.StatusNotFound, JavaAPIResponse{
Code: 404,
Message: "Camera not found",
Success: false,
})
return
}
apiCamera := JavaCamera{
ID: fmt.Sprintf("%d", camera.CameraID),
Name: getStringValue(camera.CameraName),
IP: camera.IP,
Port: camera.Port,
Username: getStringValue(camera.Username),
RTSPURL: camera.URL,
Status: "online",
Enabled: camera.DelFlag == "0",
DeviceType: getStringValue(camera.DeviceType),
UnitCode: getStringValue(camera.UnitCode),
CreatedAt: getTimeValue(camera.CreateTime),
UpdatedAt: getTimeValue(camera.UpdateTime),
PlayURLs: generatePlayURLs(fmt.Sprintf("%d", camera.CameraID)),
}
c.JSON(http.StatusOK, JavaAPIResponse{
Code: 200,
Message: "Success",
Success: true,
Data: apiCamera,
})
} else {
// 从流配置获取
if !Storage.StreamExist(cameraID) {
c.JSON(http.StatusNotFound, JavaAPIResponse{
Code: 404,
Message: "Stream not found",
Success: false,
})
return
}
camera := JavaCamera{
ID: cameraID,
Name: fmt.Sprintf("Stream %s", cameraID),
Status: "online",
Enabled: true,
PlayURLs: generatePlayURLs(cameraID),
}
c.JSON(http.StatusOK, JavaAPIResponse{
Code: 200,
Message: "Success",
Success: true,
Data: camera,
})
}
}
// HTTPJavaAPISystemInfo 获取系统信息
func HTTPJavaAPISystemInfo(c *gin.Context) {
systemInfo := map[string]interface{}{
"version": "1.0.0",
"database_enabled": Storage.Server.DatabaseEnabled,
"demo_enabled": Storage.ServerHTTPDemo(),
"total_streams": len(Storage.Streams),
"server_time": time.Now().Format(time.RFC3339),
}
if Storage.Server.DatabaseEnabled {
cameras, err := Storage.DatabaseGetCameras()
if err == nil {
systemInfo["total_cameras"] = len(cameras)
onlineCount := 0
for _, camera := range cameras {
if camera.DelFlag == "0" { // 删除标志为0表示在线
onlineCount++
}
}
systemInfo["online_cameras"] = onlineCount
}
}
c.JSON(http.StatusOK, JavaAPIResponse{
Code: 200,
Message: "Success",
Success: true,
Data: systemInfo,
})
}
// generatePlayURLs 生成播放地址
func generatePlayURLs(streamID string) PlayURLs {
baseURL := "http://localhost:8083" // 可以从配置获取
return PlayURLs{
HLS: fmt.Sprintf("%s/stream/%s/channel/0/hls/live/index.m3u8", baseURL, streamID),
WebRTC: fmt.Sprintf("%s/pages/player/webrtc/%s/0", baseURL, streamID),
MSE: fmt.Sprintf("%s/pages/player/mse/%s/0", baseURL, streamID),
All: fmt.Sprintf("%s/pages/player/all/%s/0", baseURL, streamID),
}
}