NextGB, web demo powerd by vue
This commit is contained in:
@@ -1,137 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/ossrs/srs-sip/pkg/service"
|
||||
)
|
||||
|
||||
func (h *HttpApiServer) RegisterRoutes(router *mux.Router) {
|
||||
|
||||
apiV1Router := router.PathPrefix("/srs-sip/v1").Subrouter()
|
||||
|
||||
// Add Auth middleware
|
||||
//apiV1Router.Use(authMiddleware)
|
||||
|
||||
apiV1Router.HandleFunc("/devices", h.ApiListDevices).Methods(http.MethodGet)
|
||||
apiV1Router.HandleFunc("/devices/{id}/channels", h.ApiGetChannelByDeviceId).Methods(http.MethodGet)
|
||||
apiV1Router.HandleFunc("/channels", h.ApiGetAllChannels).Methods(http.MethodGet)
|
||||
|
||||
apiV1Router.HandleFunc("/invite", h.ApiInvite).Methods(http.MethodPost)
|
||||
apiV1Router.HandleFunc("/bye", h.ApiBye).Methods(http.MethodPost)
|
||||
apiV1Router.HandleFunc("/ptz", h.ApiPTZControl).Methods(http.MethodPost)
|
||||
|
||||
apiV1Router.HandleFunc("", h.GetAPIRoutes(apiV1Router)).Methods(http.MethodGet)
|
||||
|
||||
router.HandleFunc("/srs-sip", h.ApiGetAPIVersion).Methods(http.MethodGet)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) RespondWithJSON(w http.ResponseWriter, code int, data interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
wrapper := map[string]interface{}{
|
||||
"code": code,
|
||||
"data": data,
|
||||
}
|
||||
json.NewEncoder(w).Encode(wrapper)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) RespondWithJSONSimple(w http.ResponseWriter, jsonStr string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(jsonStr))
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) GetAPIRoutes(router *mux.Router) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var routes []map[string]string
|
||||
|
||||
router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
path, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
methods, err := route.GetMethods()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, method := range methods {
|
||||
routes = append(routes, map[string]string{
|
||||
"method": method,
|
||||
"path": path,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
h.RespondWithJSON(w, 0, routes)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetAPIVersion(w http.ResponseWriter, r *http.Request) {
|
||||
h.RespondWithJSONSimple(w, `{"version": "v1"}`)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiListDevices(w http.ResponseWriter, r *http.Request) {
|
||||
list := service.DM.GetDevices()
|
||||
h.RespondWithJSON(w, 0, list)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetChannelByDeviceId(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
channels := service.DM.ApiGetChannelByDeviceId(id)
|
||||
h.RespondWithJSON(w, 0, channels)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetAllChannels(w http.ResponseWriter, r *http.Request) {
|
||||
channels := service.DM.GetAllVideoChannels()
|
||||
h.RespondWithJSON(w, 0, channels)
|
||||
}
|
||||
|
||||
// request: {"device_id": "1", "channel_id": "1", "sub_stream": 0}
|
||||
// response: {"code": 0, "data": {"channel_id": "1", "url": "webrtc://"}}
|
||||
func (h *HttpApiServer) ApiInvite(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse request
|
||||
var req map[string]string
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Get device and channel
|
||||
deviceID := req["device_id"]
|
||||
channelID := req["channel_id"]
|
||||
//subStream := req["sub_stream"]
|
||||
|
||||
code := 0
|
||||
url := ""
|
||||
|
||||
defer func() {
|
||||
data := map[string]string{
|
||||
"channel_id": channelID,
|
||||
"url": url,
|
||||
}
|
||||
h.RespondWithJSON(w, code, data)
|
||||
}()
|
||||
|
||||
if err := h.sipSvr.Uas.Invite(deviceID, channelID); err != nil {
|
||||
code = http.StatusInternalServerError
|
||||
return
|
||||
}
|
||||
c, ok := h.sipSvr.Uas.GetVideoChannelStatue(channelID)
|
||||
if !ok {
|
||||
code = http.StatusInternalServerError
|
||||
return
|
||||
}
|
||||
url = "webrtc://" + h.conf.MediaAddr + "/live/" + c.Ssrc
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiBye(w http.ResponseWriter, r *http.Request) {
|
||||
h.RespondWithJSONSimple(w, `{"msg":"Not implemented"}`)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiPTZControl(w http.ResponseWriter, r *http.Request) {
|
||||
h.RespondWithJSONSimple(w, `{"msg":"Not implemented"}`)
|
||||
}
|
||||
+19
-19
@@ -2,13 +2,10 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/ossrs/go-oryx-lib/logger"
|
||||
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/ossrs/go-oryx-lib/logger"
|
||||
"github.com/ossrs/srs-sip/pkg/config"
|
||||
"github.com/ossrs/srs-sip/pkg/service"
|
||||
)
|
||||
@@ -25,21 +22,24 @@ func NewHttpApiServer(r0 interface{}, svr *service.Service) (*HttpApiServer, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) Start() {
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
h.RegisterRoutes(router)
|
||||
func (h *HttpApiServer) Start(router *mux.Router) {
|
||||
// 添加版本检查路由到主路由器
|
||||
router.HandleFunc("/srs-sip", h.ApiGetAPIVersion).Methods(http.MethodGet)
|
||||
|
||||
headers := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"})
|
||||
methods := handlers.AllowedMethods([]string{"GET", "POST", "PUT", "DELETE", "OPTIONS"})
|
||||
origins := handlers.AllowedOrigins([]string{"*"})
|
||||
// 创建一个子路由,所有API都以/srs-sip/v1为前缀
|
||||
apiRouter := router.PathPrefix("/srs-sip/v1").Subrouter()
|
||||
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
addr := fmt.Sprintf(":%v", h.conf.APIPort)
|
||||
logger.Tf(ctx, "http api listen on %s", addr)
|
||||
err := http.ListenAndServe(addr, handlers.CORS(headers, methods, origins)(router))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
logger.Tf(context.Background(), "Registering API routes under /srs-sip/v1")
|
||||
h.RegisterRoutes(apiRouter)
|
||||
|
||||
// 打印所有注册的路由,包含更详细的信息
|
||||
router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
pathTemplate, _ := route.GetPathTemplate()
|
||||
pathRegexp, _ := route.GetPathRegexp()
|
||||
methods, _ := route.GetMethods()
|
||||
queries, _ := route.GetQueriesTemplates()
|
||||
logger.Tf(context.Background(), "Route Details: Path=%v, Regexp=%v, Methods=%v, Queries=%v",
|
||||
pathTemplate, pathRegexp, methods, queries)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/ossrs/srs-sip/pkg/models"
|
||||
"github.com/ossrs/srs-sip/pkg/service"
|
||||
)
|
||||
|
||||
func (h *HttpApiServer) RegisterRoutes(router *mux.Router) {
|
||||
// Add Auth middleware
|
||||
//apiV1Router.Use(authMiddleware)
|
||||
|
||||
router.HandleFunc("/devices", h.ApiListDevices).Methods(http.MethodGet)
|
||||
router.HandleFunc("/devices/{id}/channels", h.ApiGetChannelByDeviceId).Methods(http.MethodGet)
|
||||
router.HandleFunc("/channels", h.ApiGetAllChannels).Methods(http.MethodGet)
|
||||
|
||||
router.HandleFunc("/invite", h.ApiInvite).Methods(http.MethodPost)
|
||||
router.HandleFunc("/bye", h.ApiBye).Methods(http.MethodPost)
|
||||
router.HandleFunc("/ptz", h.ApiPTZControl).Methods(http.MethodPost)
|
||||
router.HandleFunc("/pause", h.ApiPause).Methods(http.MethodPost)
|
||||
router.HandleFunc("/resume", h.ApiResume).Methods(http.MethodPost)
|
||||
router.HandleFunc("/speed", h.ApiSpeed).Methods(http.MethodPost)
|
||||
|
||||
router.HandleFunc("/query-record", h.ApiQueryRecord).Methods(http.MethodPost)
|
||||
|
||||
// 媒体服务器相关接口,查询,新增,删除,用restful风格
|
||||
router.HandleFunc("/media-servers", h.ApiListMediaServers).Methods(http.MethodGet)
|
||||
router.HandleFunc("/media-servers", h.ApiAddMediaServer).Methods(http.MethodPost)
|
||||
router.HandleFunc("/media-servers/{id}", h.ApiDeleteMediaServer).Methods(http.MethodDelete)
|
||||
router.HandleFunc("/media-servers/default/{id}", h.ApiSetDefaultMediaServer).Methods(http.MethodPost)
|
||||
|
||||
router.HandleFunc("", h.GetAPIRoutes(router)).Methods(http.MethodGet)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) RespondWithJSON(w http.ResponseWriter, code int, data interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
wrapper := models.CommonResponse{
|
||||
Code: code,
|
||||
Data: data,
|
||||
}
|
||||
json.NewEncoder(w).Encode(wrapper)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) RespondWithJSONSimple(w http.ResponseWriter, jsonStr string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(jsonStr))
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) GetAPIRoutes(router *mux.Router) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var routes []map[string]string
|
||||
|
||||
router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
|
||||
path, err := route.GetPathTemplate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
methods, err := route.GetMethods()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, method := range methods {
|
||||
routes = append(routes, map[string]string{
|
||||
"method": method,
|
||||
"path": path,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
h.RespondWithJSON(w, 0, routes)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetAPIVersion(w http.ResponseWriter, r *http.Request) {
|
||||
h.RespondWithJSONSimple(w, `{"version": "v1"}`)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiListDevices(w http.ResponseWriter, r *http.Request) {
|
||||
list := service.DM.GetDevices()
|
||||
h.RespondWithJSON(w, 0, list)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetChannelByDeviceId(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
channels := service.DM.ApiGetChannelByDeviceId(id)
|
||||
h.RespondWithJSON(w, 0, channels)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiGetAllChannels(w http.ResponseWriter, r *http.Request) {
|
||||
channels := service.DM.GetAllVideoChannels()
|
||||
h.RespondWithJSON(w, 0, channels)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiInvite(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.InviteRequest
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
session, err := h.sipSvr.Uas.Invite(req)
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
response := models.InviteResponse{
|
||||
ChannelID: req.ChannelID,
|
||||
URL: session.URL,
|
||||
}
|
||||
h.RespondWithJSON(w, 0, response)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiBye(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.ByeRequest
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.sipSvr.Uas.Bye(req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiPause(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.PauseRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.sipSvr.Uas.Pause(req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiResume(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.ResumeRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.sipSvr.Uas.Resume(req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiSpeed(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.SpeedRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.sipSvr.Uas.Speed(req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
// request: {"device_id": "1", "channel_id": "1", "ptz": "up", "speed": "1}
|
||||
func (h *HttpApiServer) ApiPTZControl(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.PTZControlRequest
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
code := 0
|
||||
msg := ""
|
||||
defer func() {
|
||||
h.RespondWithJSON(w, code, map[string]string{"msg": msg})
|
||||
}()
|
||||
if err := h.sipSvr.Uas.ControlPTZ(req.DeviceID, req.ChannelID, req.PTZ, req.Speed); err != nil {
|
||||
code = http.StatusInternalServerError
|
||||
msg = err.Error()
|
||||
return
|
||||
}
|
||||
msg = "success"
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiQueryRecord(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.QueryRecordRequest
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
records, err := h.sipSvr.Uas.QueryRecord(req.DeviceID, req.ChannelID, req.StartTime, req.EndTime)
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
h.RespondWithJSON(w, 0, records)
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiListMediaServers(w http.ResponseWriter, r *http.Request) {
|
||||
servers, err := service.MediaDB.ListMediaServers()
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, servers)
|
||||
}
|
||||
|
||||
// request: {"name": "srs1", "ip": "192.168.1.100", "port": 1935, "type": "SRS", "username": "admin", "password": "123456"}
|
||||
func (h *HttpApiServer) ApiAddMediaServer(w http.ResponseWriter, r *http.Request) {
|
||||
var req models.MediaServerRequest
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if req.Name == "" || req.IP == "" || req.Port == 0 || req.Type == "" {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": "name, ip, port and type are required"})
|
||||
return
|
||||
}
|
||||
|
||||
// 添加到数据库
|
||||
if err := service.MediaDB.AddMediaServer(req.Name, req.Type, req.IP, req.Port, req.Username, req.Password, req.Secret, req.IsDefault); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiDeleteMediaServer(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": "invalid id"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.MediaDB.DeleteMediaServer(id); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
|
||||
func (h *HttpApiServer) ApiSetDefaultMediaServer(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
h.RespondWithJSON(w, http.StatusBadRequest, map[string]string{"msg": "invalid id"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := service.MediaDB.SetDefaultMediaServer(id); err != nil {
|
||||
h.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"msg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
h.RespondWithJSON(w, 0, map[string]string{"msg": "success"})
|
||||
}
|
||||
Reference in New Issue
Block a user