# Java项目集成RTSPtoWeb指南 本文档说明如何将RTSPtoWeb项目集成到Java项目中,实现摄像头管理和视频流展示功能。 ## 集成方案 ### 方案一:嵌入式集成(推荐) 将RTSPtoWeb的前端页面嵌入到Java Web项目中,通过iframe或直接集成HTML。 #### 1. 嵌入整个管理界面 ```html ``` #### 2. 嵌入特定功能页面 ```html ``` ### 方案二:API集成 通过REST API调用RTSPtoWeb的功能,在Java项目中实现自定义界面。 #### Java HTTP客户端示例 ```java import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URI; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.JsonNode; public class RTSPtoWebClient { private final String baseUrl; private final HttpClient httpClient; private final ObjectMapper objectMapper; public RTSPtoWebClient(String baseUrl) { this.baseUrl = baseUrl; this.httpClient = HttpClient.newHttpClient(); this.objectMapper = new ObjectMapper(); } // 获取所有摄像头 public JsonNode getAllCameras() throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/cameras")) .GET() .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to get cameras: " + response.statusCode()); } } // 根据单位代码获取摄像头 public JsonNode getCamerasByUnitCode(String unitCode) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/cameras/unit/" + unitCode)) .GET() .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to get cameras by unit: " + response.statusCode()); } } // 获取特定摄像头信息 public JsonNode getCamera(String cameraId) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/camera/" + cameraId)) .GET() .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to get camera: " + response.statusCode()); } } // 添加摄像头 public JsonNode addCamera(CameraData cameraData) throws Exception { String jsonBody = objectMapper.writeValueAsString(cameraData); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/camera/add")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to add camera: " + response.statusCode()); } } // 更新摄像头 public JsonNode updateCamera(String cameraId, CameraData cameraData) throws Exception { String jsonBody = objectMapper.writeValueAsString(cameraData); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/camera/" + cameraId)) .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to update camera: " + response.statusCode()); } } // 删除摄像头 public boolean deleteCamera(String cameraId) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/camera/" + cameraId)) .DELETE() .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); return response.statusCode() == 200; } // 刷新摄像头状态 public JsonNode refreshCameras() throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/cameras/refresh")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString("{}")) .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to refresh cameras: " + response.statusCode()); } } // 获取视频流列表 public JsonNode getStreams() throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "/streams")) .GET() .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return objectMapper.readTree(response.body()); } else { throw new RuntimeException("Failed to get streams: " + response.statusCode()); } } // 生成播放URL public String getPlayUrl(String cameraId, int channel, String type) { switch (type.toLowerCase()) { case "hls": return baseUrl + "/stream/" + cameraId + "/channel/" + channel + "/hls/live/index.m3u8"; case "webrtc": return baseUrl + "/pages/player/webrtc/" + cameraId + "/" + channel; case "mse": return baseUrl + "/pages/player/mse/" + cameraId + "/" + channel; default: return baseUrl + "/pages/player/all/" + cameraId + "/" + channel; } } } // 摄像头数据模型 class CameraData { public String name; public String ip; public int port = 554; public String username; public String password; public String rtsp_url; public String camera_produce; public String device_type; public String unit_code; public String nvr_produce; public String nvr_path; public String play_back; public boolean enabled = true; public int user_id; public int dept_id; // 构造函数、getter和setter方法 public CameraData() {} public CameraData(String name, String ip, String username, String password, String rtspUrl) { this.name = name; this.ip = ip; this.username = username; this.password = password; this.rtsp_url = rtspUrl; } } ``` #### Spring Boot Controller示例 ```java import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import com.fasterxml.jackson.databind.JsonNode; @Controller @RequestMapping("/camera") public class CameraController { private final RTSPtoWebClient rtspClient; public CameraController() { this.rtspClient = new RTSPtoWebClient("http://localhost:8083"); } // 摄像头管理页面 @GetMapping("/management") public String cameraManagement(Model model) { try { JsonNode cameras = rtspClient.getAllCameras(); model.addAttribute("cameras", cameras); } catch (Exception e) { model.addAttribute("error", "获取摄像头列表失败: " + e.getMessage()); } return "camera/management"; } // 根据单位获取摄像头 @GetMapping("/unit/{unitCode}") @ResponseBody public JsonNode getCamerasByUnit(@PathVariable String unitCode) { try { return rtspClient.getCamerasByUnitCode(unitCode); } catch (Exception e) { throw new RuntimeException("获取摄像头失败", e); } } // 视频监控页面 @GetMapping("/monitor") public String videoMonitor(Model model) { try { JsonNode cameras = rtspClient.getAllCameras(); model.addAttribute("cameras", cameras); } catch (Exception e) { model.addAttribute("error", "获取摄像头列表失败: " + e.getMessage()); } return "camera/monitor"; } // 添加摄像头 @PostMapping("/add") @ResponseBody public JsonNode addCamera(@RequestBody CameraData cameraData) { try { return rtspClient.addCamera(cameraData); } catch (Exception e) { throw new RuntimeException("添加摄像头失败", e); } } // 获取播放URL @GetMapping("/{cameraId}/play-url") @ResponseBody public String getPlayUrl(@PathVariable String cameraId, @RequestParam(defaultValue = "0") int channel, @RequestParam(defaultValue = "hls") String type) { return rtspClient.getPlayUrl(cameraId, channel, type); } } ``` ### 方案三:前端JavaScript集成 在Java项目的前端页面中直接使用RTSPtoWeb提供的JavaScript API。 ```html 视频监控系统
``` ## 部署配置 ### 1. RTSPtoWeb服务配置 确保RTSPtoWeb服务正常运行: ```bash # 启动RTSPtoWeb服务 cd RTSPtoWeb go run . --config config.json ``` ### 2. 跨域配置 如果Java项目和RTSPtoWeb运行在不同端口,需要配置CORS: 在RTSPtoWeb的`apiHTTPServer.go`中添加CORS中间件: ```go func CORSMiddleware() gin.HandlerFunc { return gin.HandlerFunc(func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Credentials", "true") c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Header("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() }) } ``` ### 3. 反向代理配置 使用Nginx反向代理统一端口: ```nginx server { listen 80; server_name your-domain.com; # Java应用 location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # RTSPtoWeb API location /rtsp-api/ { proxy_pass http://localhost:8083/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # WebSocket支持 location /rtsp-api/stream/ { proxy_pass http://localhost:8083/stream/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } } ``` ## API接口文档 ### 摄像头管理API | 方法 | 路径 | 描述 | |------|------|------| | GET | `/cameras` | 获取所有摄像头列表 | | GET | `/cameras/unit/{unitcode}` | 根据单位代码获取摄像头 | | GET | `/camera/{id}` | 获取特定摄像头信息 | | POST | `/camera/add` | 添加新摄像头 | | PUT | `/camera/{id}` | 更新摄像头信息 | | DELETE | `/camera/{id}` | 删除摄像头 | | POST | `/cameras/refresh` | 刷新摄像头状态 | ### 视频流API | 方法 | 路径 | 描述 | |------|------|------| | GET | `/streams` | 获取所有视频流列表 | | GET | `/stream/{id}/channel/{channel}/hls/live/index.m3u8` | HLS播放地址 | | GET | `/pages/player/webrtc/{id}/{channel}` | WebRTC播放页面 | | GET | `/pages/player/mse/{id}/{channel}` | MSE播放页面 | | GET | `/pages/player/all/{id}/{channel}` | 通用播放页面 | ## 注意事项 1. **数据库配置**:确保RTSPtoWeb的数据库配置正确,摄像头数据存储在数据库中。 2. **网络配置**:确保Java项目能够访问RTSPtoWeb服务的端口(默认8083)。 3. **安全考虑**:在生产环境中,建议配置认证和授权机制。 4. **性能优化**:对于大量摄像头的场景,建议实现分页和缓存机制。 5. **错误处理**:实现完善的错误处理和重试机制。 6. **监控告警**:建议添加服务健康检查和告警机制。 ## 示例项目结构 ``` java-rtsp-integration/ ├── src/main/java/ │ ├── controller/ │ │ ├── CameraController.java │ │ └── VideoController.java │ ├── service/ │ │ ├── RTSPtoWebClient.java │ │ └── CameraService.java │ └── model/ │ └── CameraData.java ├── src/main/resources/ │ ├── templates/ │ │ ├── camera/ │ │ │ ├── management.html │ │ │ └── monitor.html │ │ └── layout.html │ └── static/ │ ├── css/ │ └── js/ └── pom.xml ``` 通过以上集成方案,可以在Java项目中完整地使用RTSPtoWeb的摄像头管理和视频流功能。