diff --git a/proxy/srs-api-proxy.go b/proxy/srs-api-proxy.go index 2b7f63cb9f..1198c9237a 100644 --- a/proxy/srs-api-proxy.go +++ b/proxy/srs-api-proxy.go @@ -30,24 +30,78 @@ type SrsClient struct { RecvBytes int `json:"recv_bytes"` } +type SrsApiCodeResponse struct { + Code int `json:"code"` +} + +type SrsAPICommonResponse struct { + SrsApiCodeResponse + Server string `json:"server"` + Service string `json:"service"` + Pid string `json:"pid"` +} + type SrsClientResponse struct { - Code int `json:"code"` - Server string `json:"server"` - Service string `json:"service"` - Pid string `json:"pid"` - Client SrsClient `json:"client"` + SrsAPICommonResponse + Client SrsClient `json:"client"` } type SrsClientsResponse struct { - Code int `json:"code"` - Server string `json:"server"` - Service string `json:"service"` - Pid string `json:"pid"` + SrsAPICommonResponse Clients []SrsClient `json:"clients"` } -type SrsClientDeleteResponse struct { - Code int `json:"code"` +type SrsKbps struct { + Recv_30s uint32 `json:"recv_30s"` + Send_30s uint32 `json:"send_30s"` +} + +type SrsPublish struct { + Active bool `json:"active"` + Cid string `json:"cid"` +} + +type SrsVideo struct { + Codec string `json:"codec"` + Profile string `json:"profile"` + Level string `json:"level"` + Width uint32 `json:"width"` + Height uint32 `json:"height"` +} + +type SrsAudio struct { + Codec string `json:"codec"` + Sample_rate uint32 `json:"sample_rate"` + Channel uint8 `json:"channel"` + Profile string `json:"profile"` +} + +type SrsStream struct { + Id string `json:"id"` + Name string `json:"name"` + Vhost string `json:"vhost"` + App string `json:"app"` + TcUrl string `json:"tcUrl"` + Url string `json:"url"` + Live_ms uint64 `json:"live_ms"` + Clients uint32 `json:"clients"` + Frames uint32 `json:"frames"` + Send_bytes uint32 `json:"send_bytes"` + Recv_bytes uint32 `json:"recv_bytes"` + Kbps SrsKbps `json:"kbps"` + Publish SrsPublish `json:"publish"` + Video SrsVideo `json:"video"` + Audio SrsAudio `json:"audio"` +} + +type SrsStreamResponse struct { + SrsAPICommonResponse + Stream SrsStream `json:"stream"` +} + +type SrsStreamsResponse struct { + SrsAPICommonResponse + Streams []SrsStream `json:"streams"` } type SrsApiProxy struct { @@ -83,7 +137,7 @@ func proxySrsClientsAPI(ctx context.Context, servers []*SRSServer, w http.Respon for _, server := range servers { if ret, err := server.ApiRequest(ctx, r, body); err == nil { logger.Df(ctx, "response %v", string(ret)) - var res SrsClientDeleteResponse + var res SrsApiCodeResponse if err := json.Unmarshal(ret, &res); err == nil && res.Code == 0 { apiResponse(ctx, w, r, res) return nil @@ -126,5 +180,53 @@ func proxySrsClientsAPI(ctx context.Context, servers []*SRSServer, w http.Respon } func proxySrsStreamsAPI(ctx context.Context, servers []*SRSServer, w http.ResponseWriter, r *http.Request) error { + defer r.Body.Close() + + streamId := "" + if strings.HasPrefix(r.URL.Path, "/api/v1/streams/") { + streamId = r.URL.Path[len("/api/v1/streams/"):] + } + logger.Df(ctx, "%v %v streamId=%v", r.Method, r.URL.Path, streamId) + + body, err := io.ReadAll(r.Body) + if err != nil { + apiError(ctx, w, r, err, http.StatusInternalServerError) + return errors.Wrapf(err, "read request body err") + } + if r.Method != http.MethodGet { + err := errors.Errorf("Unsupported http method type %v", r.Method) + apiError(ctx, w, r, err, http.StatusBadRequest) + return err + } + if len(streamId) > 0 { + var stream SrsStreamResponse + for _, server := range servers { + if ret, err := server.ApiRequest(ctx, r, body); err == nil { + if err := json.Unmarshal(ret, &stream); err == nil && stream.Code == 0 { + apiResponse(ctx, w, r, stream) + return nil + } + } + } + ret := SrsApiCodeResponse{ + Code: 2048, + } + apiResponse(ctx, w, r, ret) + return nil + } else { + var streams SrsStreamsResponse + for _, server := range servers { + var res SrsStreamsResponse + if ret, err := server.ApiRequest(ctx, r, body); err == nil { + if err := json.Unmarshal(ret, &res); err == nil && res.Code == 0 { + streams.Streams = append(streams.Streams, res.Streams...) + } + } + } + + apiResponse(ctx, w, r, streams) + return nil + } + return nil }