184 lines
4.3 KiB
Go
184 lines
4.3 KiB
Go
|
|
/**
|
|||
|
|
* package api
|
|||
|
|
*
|
|||
|
|
* 媒体服务监控 API 处理器
|
|||
|
|
* 功能:
|
|||
|
|
* 1. 查看媒体服务器状态
|
|||
|
|
* 2. 查看活跃房间和流
|
|||
|
|
* 3. 管理桥接器
|
|||
|
|
*/
|
|||
|
|
package api
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"xk-websocket-v2/internal/mediaserver"
|
|||
|
|
"xk-websocket-v2/internal/utils"
|
|||
|
|
|
|||
|
|
"github.com/gin-gonic/gin"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// MediaServerStatusResponse 媒体服务器状态响应
|
|||
|
|
type MediaServerStatusResponse struct {
|
|||
|
|
Enabled bool `json:"enabled"`
|
|||
|
|
Config map[string]interface{} `json:"config"`
|
|||
|
|
RoomCount int `json:"room_count"`
|
|||
|
|
SFUTrackCount int `json:"sfu_track_count"`
|
|||
|
|
RTMPStreamCount int `json:"rtmp_stream_count"`
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetMediaServerStatusHandler 获取媒体服务器状态
|
|||
|
|
// GET /api/media/status
|
|||
|
|
func GetMediaServerStatusHandler(c *gin.Context) {
|
|||
|
|
ms := mediaserver.GetServer()
|
|||
|
|
config := ms.GetConfig()
|
|||
|
|
|
|||
|
|
if config == nil {
|
|||
|
|
utils.Error(c, 503, "媒体服务未配置")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
response := MediaServerStatusResponse{
|
|||
|
|
Enabled: config.Enabled,
|
|||
|
|
RoomCount: ms.GetRoomCount(),
|
|||
|
|
Config: map[string]interface{}{
|
|||
|
|
"public_ip": config.PublicIP,
|
|||
|
|
"webrtc_port": config.WebRTCPort,
|
|||
|
|
"rtmp_port": config.RTMPPort,
|
|||
|
|
"http_flv_port": config.HTTPFLVPort,
|
|||
|
|
"max_room_size": config.MaxRoomSize,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取 SFU 轨道数
|
|||
|
|
if sfu := ms.GetSFU(); sfu != nil {
|
|||
|
|
response.SFUTrackCount = sfu.GetTrackCount()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取 RTMP 流数
|
|||
|
|
if rtmp := ms.GetRTMP(); rtmp != nil {
|
|||
|
|
response.RTMPStreamCount = rtmp.GetStreamCount()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
utils.SuccessWithData(c, response, "获取成功")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetAllRoomsHandler 获取所有房间
|
|||
|
|
// GET /api/media/rooms
|
|||
|
|
func GetAllRoomsHandler(c *gin.Context) {
|
|||
|
|
ms := mediaserver.GetServer()
|
|||
|
|
rooms := ms.GetAllRooms()
|
|||
|
|
|
|||
|
|
utils.SuccessWithData(c, gin.H{
|
|||
|
|
"count": len(rooms),
|
|||
|
|
"rooms": rooms,
|
|||
|
|
}, "获取成功")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRoomDetailHandler 获取房间详情
|
|||
|
|
// GET /api/media/rooms/:room_id
|
|||
|
|
func GetRoomDetailHandler(c *gin.Context) {
|
|||
|
|
roomID := c.Param("room_id")
|
|||
|
|
if roomID == "" {
|
|||
|
|
utils.BadRequest(c, "房间ID不能为空")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ms := mediaserver.GetServer()
|
|||
|
|
room := ms.GetRoom(roomID)
|
|||
|
|
if room == nil {
|
|||
|
|
utils.NotFound(c, "房间不存在")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
info := room.GetInfo()
|
|||
|
|
|
|||
|
|
// 获取桥接信息
|
|||
|
|
bm := mediaserver.GetBridgeManager()
|
|||
|
|
bridge := bm.GetBridge(roomID)
|
|||
|
|
var bridgeInfo map[string]interface{}
|
|||
|
|
if bridge != nil && bridge.IsRunning() {
|
|||
|
|
w2r, r2w := bridge.GetAllConverters()
|
|||
|
|
w2rCount, r2wCount := bridge.GetConverterCount()
|
|||
|
|
bridgeInfo = map[string]interface{}{
|
|||
|
|
"running": true,
|
|||
|
|
"webrtc_to_rtmp": w2rCount,
|
|||
|
|
"rtmp_to_webrtc": r2wCount,
|
|||
|
|
"w2r_converters": w2r,
|
|||
|
|
"r2w_converters": r2w,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
utils.SuccessWithData(c, gin.H{
|
|||
|
|
"room": info,
|
|||
|
|
"bridge": bridgeInfo,
|
|||
|
|
}, "获取成功")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRTMPStreamsHandler 获取 RTMP 流列表
|
|||
|
|
// GET /api/media/rtmp/streams
|
|||
|
|
func GetRTMPStreamsHandler(c *gin.Context) {
|
|||
|
|
ms := mediaserver.GetServer()
|
|||
|
|
rtmp := ms.GetRTMP()
|
|||
|
|
|
|||
|
|
if rtmp == nil {
|
|||
|
|
utils.Error(c, 503, "RTMP服务未启用")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
roomID := c.Query("room_id")
|
|||
|
|
|
|||
|
|
var streams []*mediaserver.RTMPStream
|
|||
|
|
if roomID != "" {
|
|||
|
|
streams = rtmp.GetStreamsByRoom(roomID)
|
|||
|
|
} else {
|
|||
|
|
// 获取所有流(简化实现:只返回数量)
|
|||
|
|
utils.SuccessWithData(c, gin.H{
|
|||
|
|
"count": rtmp.GetStreamCount(),
|
|||
|
|
}, "获取成功")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
utils.SuccessWithData(c, gin.H{
|
|||
|
|
"count": len(streams),
|
|||
|
|
"streams": streams,
|
|||
|
|
}, "获取成功")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// CloseRoomHandler 关闭房间
|
|||
|
|
// POST /api/media/rooms/:room_id/close
|
|||
|
|
func CloseRoomHandler(c *gin.Context) {
|
|||
|
|
roomID := c.Param("room_id")
|
|||
|
|
if roomID == "" {
|
|||
|
|
utils.BadRequest(c, "房间ID不能为空")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ms := mediaserver.GetServer()
|
|||
|
|
room := ms.GetRoom(roomID)
|
|||
|
|
if room == nil {
|
|||
|
|
utils.NotFound(c, "房间不存在")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 移除桥接
|
|||
|
|
bm := mediaserver.GetBridgeManager()
|
|||
|
|
bm.RemoveBridge(roomID)
|
|||
|
|
|
|||
|
|
// 移除房间
|
|||
|
|
ms.RemoveRoom(roomID)
|
|||
|
|
|
|||
|
|
utils.Success(c, "房间已关闭")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// RegisterMediaRoutes 注册媒体相关路由
|
|||
|
|
func RegisterMediaRoutes(router *gin.RouterGroup) {
|
|||
|
|
mediaGroup := router.Group("/media")
|
|||
|
|
{
|
|||
|
|
mediaGroup.GET("/status", GetMediaServerStatusHandler)
|
|||
|
|
mediaGroup.GET("/rooms", GetAllRoomsHandler)
|
|||
|
|
mediaGroup.GET("/rooms/:room_id", GetRoomDetailHandler)
|
|||
|
|
mediaGroup.POST("/rooms/:room_id/close", CloseRoomHandler)
|
|||
|
|
mediaGroup.GET("/rtmp/streams", GetRTMPStreamsHandler)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|