Files
donut/internal/web/handlers/signaling.go
Leandro Moreira 33710100a5 add mpeg-ts prober
2024-02-09 09:49:17 -03:00

149 lines
3.5 KiB
Go

package handlers
import (
"context"
"encoding/json"
"net/http"
"github.com/flavioribeiro/donut/internal/controllers"
"github.com/flavioribeiro/donut/internal/controllers/probers"
"github.com/flavioribeiro/donut/internal/entities"
"go.uber.org/zap"
)
type SignalingHandler struct {
c *entities.Config
l *zap.SugaredLogger
webRTCController *controllers.WebRTCController
srtController *controllers.SRTController
streamingController *controllers.StreamingController
srtMpegTSprober *probers.SrtMpegTs
}
func NewSignalingHandler(
c *entities.Config,
log *zap.SugaredLogger,
webRTCController *controllers.WebRTCController,
srtController *controllers.SRTController,
streamingController *controllers.StreamingController,
srtMpegTSprober *probers.SrtMpegTs,
) *SignalingHandler {
return &SignalingHandler{
c: c,
l: log,
webRTCController: webRTCController,
srtController: srtController,
streamingController: streamingController,
srtMpegTSprober: srtMpegTSprober,
}
}
func (h *SignalingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) error {
if r.Method != http.MethodPost {
h.l.Errorw("unexpected method")
return entities.ErrHTTPPostOnly
}
params := entities.RequestParams{}
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
h.l.Errorw("error while decoding request params json",
"error", err,
)
return err
}
if err := params.Valid(); err != nil {
h.l.Errorw("invalid params",
"error", err,
)
return err
}
ctx, cancel := context.WithCancel(context.Background())
peer, err := h.webRTCController.CreatePeerConnection(cancel)
if err != nil {
h.l.Errorw("error while setting up web rtc connection",
"error", err,
)
return err
}
data, err := h.srtMpegTSprober.StreamInfo(&params)
if err != nil {
h.l.Errorw("error while probing",
"error", err,
)
return err
}
h.l.Infow("stream info",
"data", data,
)
// TODO: create tracks according with SRT available streams
// Create a video track
videoTrack, err := h.webRTCController.CreateTrack(
peer,
entities.Stream{
Codec: entities.H264,
}, "video", params.SRTStreamID,
)
if err != nil {
h.l.Errorw("error while creating a web rtc track",
"error", err,
)
return err
}
metadataSender, err := h.webRTCController.CreateDataChannel(peer, entities.MetadataChannelID)
if err != nil {
h.l.Errorw("error while creating a web rtc data channel",
"error", err,
)
return err
}
if err = h.webRTCController.SetRemoteDescription(peer, params.Offer); err != nil {
h.l.Errorw("error while setting a remote web rtc description",
"error", err,
)
return err
}
localDescription, err := h.webRTCController.GatheringWebRTC(peer)
if err != nil {
h.l.Errorw("error while preparing a local web rtc description",
"error", err,
)
return err
}
srtConnection, err := h.srtController.Connect(cancel, &params)
if err != nil {
h.l.Errorw("error while connecting to an srt server",
"error", err,
)
return err
}
go h.streamingController.Stream(&entities.StreamParameters{
Cancel: cancel,
Ctx: ctx,
WebRTCConn: peer,
SRTConnection: srtConnection,
VideoTrack: videoTrack,
MetadataTrack: metadataSender,
})
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
err = json.NewEncoder(w).Encode(*localDescription)
if err != nil {
h.l.Errorw("error while encoding a local web rtc description",
"error", err,
)
return err
}
return nil
}