A signaling server for GB28181

This commit is contained in:
Haibo Chen
2024-04-17 14:31:33 +08:00
committed by chenhaibo
parent 8774b234b4
commit 0b7126b12b
50 changed files with 11136 additions and 1 deletions

137
pkg/api/api-controller.go Normal file
View File

@ -0,0 +1,137 @@
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"}`)
}

45
pkg/api/api.go Normal file
View File

@ -0,0 +1,45 @@
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/srs-sip/pkg/config"
"github.com/ossrs/srs-sip/pkg/service"
)
type HttpApiServer struct {
conf *config.MainConfig
sipSvr *service.Service
}
func NewHttpApiServer(r0 interface{}, svr *service.Service) (*HttpApiServer, error) {
return &HttpApiServer{
conf: r0.(*config.MainConfig),
sipSvr: svr,
}, nil
}
func (h *HttpApiServer) Start() {
router := mux.NewRouter().StrictSlash(true)
h.RegisterRoutes(router)
headers := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"})
methods := handlers.AllowedMethods([]string{"GET", "POST", "PUT", "DELETE", "OPTIONS"})
origins := handlers.AllowedOrigins([]string{"*"})
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)
}
}()
}