diff --git a/cmd/rtmp/rtmp.go b/cmd/rtmp/rtmp.go index 38c3b240..7be03d8a 100644 --- a/cmd/rtmp/rtmp.go +++ b/cmd/rtmp/rtmp.go @@ -1,16 +1,22 @@ package rtmp import ( + "github.com/AlexxIT/go2rtc/cmd/api" "github.com/AlexxIT/go2rtc/cmd/streams" "github.com/AlexxIT/go2rtc/pkg/rtmp" "github.com/AlexxIT/go2rtc/pkg/streamer" + "github.com/rs/zerolog/log" + "io" + "net/http" ) func Init() { - streams.HandleFunc("rtmp", handle) + streams.HandleFunc("rtmp", streamsHandle) + + api.HandleFunc("api/stream.flv", apiHandle) } -func handle(url string) (streamer.Producer, error) { +func streamsHandle(url string) (streamer.Producer, error) { conn := rtmp.NewClient(url) if err := conn.Dial(); err != nil { return nil, err @@ -20,3 +26,37 @@ func handle(url string) (streamer.Producer, error) { } return conn, nil } + +func apiHandle(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, "", http.StatusMethodNotAllowed) + return + } + + dst := r.URL.Query().Get("dst") + stream := streams.Get(dst) + if stream == nil { + http.Error(w, api.StreamNotFound, http.StatusNotFound) + return + } + + res := &http.Response{Body: r.Body, Request: r} + client, err := rtmp.Accept(res) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + if err = client.Describe(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + stream.AddProducer(client) + + if err = client.Start(); err != nil && err != io.EOF { + log.Warn().Err(err).Caller().Send() + } + + stream.RemoveProducer(client) +}