diff --git a/cmd/webrtc/webrtc.go b/cmd/webrtc/webrtc.go index 49a5e992..d5b8ef5c 100644 --- a/cmd/webrtc/webrtc.go +++ b/cmd/webrtc/webrtc.go @@ -1,6 +1,7 @@ package webrtc import ( + "encoding/json" "errors" "github.com/AlexxIT/go2rtc/cmd/api" "github.com/AlexxIT/go2rtc/cmd/app" @@ -9,10 +10,16 @@ import ( pion "github.com/pion/webrtc/v3" "github.com/rs/zerolog" "io" + "mime" "net" "net/http" ) +type jsonSdp struct { + Type string `json:"type"` + Sdp string `json:"sdp"` +} + func Init() { var cfg struct { Mod struct { @@ -145,25 +152,76 @@ func syncHandler(w http.ResponseWriter, r *http.Request) { return } + mediaType, err := DetermineMediaType(r) + if err != nil { + log.Error().Err(err).Caller().Msg("DetermineMediaType") + return + } + // get offer - offer, err := io.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { log.Error().Err(err).Caller().Msg("ioutil.ReadAll") return } - answer, err := ExchangeSDP(stream, string(offer), r.UserAgent()) + offer, err := DeserializeOffer(mediaType, body) + if err != nil { + log.Error().Err(err).Caller().Msg("DeserializeOffer") + return + } + + answer, err := ExchangeSDP(stream, offer, r.UserAgent()) if err != nil { log.Error().Err(err).Caller().Msg("ExchangeSDP") return } + response, err := SerializeAnswer(mediaType, answer) + if err != nil { + log.Error().Err(err).Caller().Msg("SerializeAnswer") + return + } + // send SDP to client - if _, err = w.Write([]byte(answer)); err != nil { + if _, err = w.Write(response); err != nil { log.Error().Err(err).Caller().Msg("w.Write") } } +func DetermineMediaType(r *http.Request) (mediaType string, err error) { + contentType := r.Header.Get("Content-Type") + if contentType != "" { + mediaType, _, err = mime.ParseMediaType(contentType) + if err != nil { + log.Error().Err(err).Caller().Msg("mime.ParseMediaType") + return + } + } else { + mediaType = "text/plain" + } + return +} + +func DeserializeOffer(mediaType string, body []byte) (offer string, err error) { + switch mediaType { + case "application/json": + var jsonOffer jsonSdp + err = json.Unmarshal(body, &jsonOffer) + if err != nil { + log.Error().Err(err).Caller().Msg("json.Unmarshal") + return + } + + offer = jsonOffer.Sdp + break + default: + offer = string(body) + break + } + return +} + func ExchangeSDP( stream *streams.Stream, offer string, userAgent string, ) (answer string, err error) { @@ -216,3 +274,23 @@ func ExchangeSDP( return } + +func SerializeAnswer(mediaType string, answer string) (response []byte, err error) { + switch mediaType { + case "application/json": + jsonAnswer := jsonSdp{ + Sdp: answer, + Type: "answer", + } + response, err = json.Marshal(jsonAnswer) + if err != nil { + log.Error().Err(err).Caller().Msg("json.Marshal") + return + } + break + default: + response = []byte(answer) + break + } + return +}