package main import ( "encoding/json" "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"` } // Camera 摄像头信息结构 type Camera 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 []Camera var total int // 如果数据库启用,从数据库获取 if Storage.ServerDatabaseEnabled() { 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 := Camera{ ID: dbCamera.ID, Name: dbCamera.Name, IP: dbCamera.IP, Port: dbCamera.Port, Username: dbCamera.Username, RTSPURL: dbCamera.RTSPURL, Status: dbCamera.Status, Enabled: dbCamera.Enabled, DeviceType: dbCamera.DeviceType, UnitCode: dbCamera.UnitCode, CreatedAt: dbCamera.CreatedAt, UpdatedAt: dbCamera.UpdatedAt, PlayURLs: generatePlayURLs(dbCamera.ID), } // 过滤条件 if unitCode != "" && camera.UnitCode != unitCode { continue } if status != "" && camera.Status != status { continue } cameras = append(cameras, camera) } } else { // 从流配置获取 streamsList := Storage.StreamsList() for streamID := range streamsList { camera := Camera{ 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 = []Camera{} } else if end > total { cameras = cameras[start:] } else { cameras = cameras[start:end] } response := JavaAPIResponse{ Code: 200, Message: "Success", Success: true, Data: CameraListResponse{ 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.StreamsList() 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 streamData != nil { 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.ServerDatabaseEnabled() { camera, err := Storage.DatabaseGetCamera(cameraID) if err != nil { c.JSON(http.StatusNotFound, JavaAPIResponse{ Code: 404, Message: "Camera not found", Success: false, }) return } apiCamera := Camera{ ID: camera.ID, Name: camera.Name, IP: camera.IP, Port: camera.Port, Username: camera.Username, RTSPURL: camera.RTSPURL, Status: camera.Status, Enabled: camera.Enabled, DeviceType: camera.DeviceType, UnitCode: camera.UnitCode, CreatedAt: camera.CreatedAt, UpdatedAt: camera.UpdatedAt, PlayURLs: generatePlayURLs(camera.ID), } 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 := Camera{ 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.ServerDatabaseEnabled(), "demo_enabled": Storage.ServerHTTPDemo(), "total_streams": len(Storage.StreamsList()), "server_time": time.Now().Format(time.RFC3339), } if Storage.ServerDatabaseEnabled() { cameras, err := Storage.DatabaseGetCameras() if err == nil { systemInfo["total_cameras"] = len(cameras) onlineCount := 0 for _, camera := range cameras { if camera.Status == "online" { 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), } }