diff --git a/core/rtmp/rtmp.go b/core/rtmp/rtmp.go index 795cc3900..eaade443a 100644 --- a/core/rtmp/rtmp.go +++ b/core/rtmp/rtmp.go @@ -1,132 +1,78 @@ package rtmp import ( - "fmt" - "io" - "net" "os" "strings" "syscall" - "time" + + "github.com/Seize/joy4/av/avutil" + "github.com/Seize/joy4/format/ts" + log "github.com/sirupsen/logrus" "github.com/gabek/owncast/config" "github.com/gabek/owncast/core" "github.com/gabek/owncast/core/ffmpeg" "github.com/gabek/owncast/utils" - "github.com/nareix/joy5/format/flv" - "github.com/nareix/joy5/format/rtmp" - - log "github.com/sirupsen/logrus" + "github.com/Seize/joy4/format" + "github.com/Seize/joy4/format/rtmp" ) var ( //IsConnected whether there is a connection or not _isConnected = false - pipePath = utils.GetTemporaryPipePath() - filePipe *os.File ) +func init() { + format.RegisterAll() +} + //Start starts the rtmp service, listening on port 1935 func Start() { + port := 1935 + server := &rtmp.Server{} - server := rtmp.NewServer() + server.HandlePublish = handlePublish - server.LogEvent = func(conn *rtmp.Conn, nc net.Conn, e int) { - log.Errorln("RTMP status:", rtmp.EventString[e]) - } - - server.OnNewConn = func(conn *rtmp.Conn) { - log.Println("OnNewConn!", conn.FlashVer) - } - - server.HandleConn = func(conn *rtmp.Conn, nc net.Conn) { - if _isConnected { - log.Errorln("stream already running; can not overtake an existing stream") - nc.Close() - } - - streamingKeyComponents := strings.Split(conn.URL.Path, "/") - streamingKey := streamingKeyComponents[len(streamingKeyComponents)-1] - - if streamingKey != config.Config.VideoSettings.StreamingKey { - log.Errorln("invalid streaming key; rejecting incoming stream") - nc.Close() - return - } - - // Record streams as FLV - syscall.Mkfifo(pipePath, 0666) - file, err := os.OpenFile(pipePath, os.O_RDWR, os.ModeNamedPipe) - if err != nil { - log.Panicln(err) - } - - filePipe = file - fmt.Println(pipePath) - - muxer := flv.NewMuxer(filePipe) - - _isConnected = true - core.SetStreamAsConnected() - - defer filePipe.Close() - - if err != nil { - panic(err) - } - - defer nc.Close() - - transcoder := ffmpeg.NewTranscoder() - go transcoder.Start() - - for { - pkt, err := conn.ReadPacket() - if err != nil { - log.Errorln(err) - - if err == io.EOF { - _isConnected = false - core.SetStreamAsDisconnected() - break - } - - return - } - - // err = muxer.WriteFileHeader() - // if err != nil { - // log.Errorln(err) - // } - - err = muxer.WritePacket(pkt) - if err != nil { - log.Errorln(err) - } - - } - } - - var lis net.Listener - var err error - if lis, err = net.Listen("tcp", fmt.Sprintf(":%d", port)); err != nil { - return + error := server.ListenAndServe() + if error != nil { + log.Panicln(error) } log.Printf("RTMP server is listening for incoming stream on port: %d", port) +} - go func() { - for { - nc, err := lis.Accept() - if err != nil { - time.Sleep(time.Second) - continue - } - go server.HandleNetConn(nc) - } - }() +func handlePublish(conn *rtmp.Conn) { + // Commented out temporarily because I have no way to set _isConnected to false after RTMP is closed. + // if _isConnected { + // log.Errorln("stream already running; can not overtake an existing stream") + // conn.Close() + // return + // } + streamingKeyComponents := strings.Split(conn.URL.Path, "/") + streamingKey := streamingKeyComponents[len(streamingKeyComponents)-1] + if streamingKey != config.Config.VideoSettings.StreamingKey { + log.Errorln("invalid streaming key; rejecting incoming stream") + conn.Close() + return + } + + pipePath := utils.GetTemporaryPipePath() + syscall.Mkfifo(pipePath, 0666) + transcoder := ffmpeg.NewTranscoder() + go transcoder.Start() + + _isConnected = true + core.SetStreamAsConnected() + + f, err := os.OpenFile(pipePath, os.O_WRONLY, os.ModeNamedPipe) + if err != nil { + panic(err) + } + + muxer := ts.NewMuxer(f) + avutil.CopyFile(muxer, conn) } //IsConnected gets whether there is an rtmp connection or not diff --git a/go.mod b/go.mod index 1f6909dd5..e515f7f05 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,7 @@ require ( github.com/libp2p/go-libp2p-peerstore v0.2.6 github.com/mssola/user_agent v0.5.2 github.com/multiformats/go-multiaddr v0.2.2 - github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 // indirect - github.com/nareix/joy5 v0.0.0-20200409150540-6c2a804a2816 + github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 github.com/radovskyb/watcher v1.0.7 github.com/sirupsen/logrus v1.6.0 github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf @@ -23,3 +22,5 @@ require ( golang.org/x/net v0.0.0-20200602114024-627f9648deb9 gopkg.in/yaml.v2 v2.3.0 ) + +replace github.com/nareix/joy4 v0.0.0 => github.com/Seize/joy4 v0.0.0 diff --git a/go.sum b/go.sum index 99f7bf9a3..1d372c74f 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIo github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Danile71/joy4 v0.0.0-20200617111000-4c92a5f18a24 h1:7y5l9RK694Unz8neWlz9bNueMRrr054h/u5ru8NgwQo= +github.com/Danile71/joy4 v0.0.0-20200617111000-4c92a5f18a24/go.mod h1:ZRwYqit2cuEv7IyWNcYVezd/DM28D6W6hUWN5z4vkn0= github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -27,8 +29,10 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75 h1:3ILjVyslFbc4jl1w5TWuvvslFD/nDfR2H8tVaMVLrEY= github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= @@ -118,6 +122,8 @@ github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiD github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gabek/joy4 v0.0.8 h1:OlG1UFDSRRMCbbhtmSvyb/URFGr8OxI1/kkDG2eyHGI= +github.com/gabek/joy4 v0.0.8/go.mod h1:44yzEqcL98n2ossWubXBgDmbrE/TC3WqQDYUUC9Xz0c= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI= @@ -810,8 +816,6 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 h1:Yp0zFEufLz0H7jzffb4UPXijavlyqlYeOg7dcyVUNnQ= github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369/go.mod h1:aFJ1ZwLjvHN4yEzE5Bkz8rD8/d8Vlj3UIuvz2yfET7I= -github.com/nareix/joy5 v0.0.0-20200409150540-6c2a804a2816 h1:YXL1GIHlL39qw2Eh8IQQIuSRwhb/lq3fMNODosQA6ic= -github.com/nareix/joy5 v0.0.0-20200409150540-6c2a804a2816/go.mod h1:KQWqnCy0MEAaiqq/A/1M4ZUAs1mv6y3tGN8ICkcyNms= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1168,6 +1172,7 @@ google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9M google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/utils/utils.go b/utils/utils.go index 43b211d6e..0568d97ad 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -9,7 +9,7 @@ import ( //GetTemporaryPipePath gets the temporary path for the streampipe.flv file func GetTemporaryPipePath() string { - return filepath.Join(os.TempDir(), "streampipe.flv") + return filepath.Join(os.TempDir(), "streampipe.ts") } //DoesFileExists checks if the file exists diff --git a/webroot/js/config.js b/webroot/js/config.js index 12e217a5c..1602ea62e 100644 --- a/webroot/js/config.js +++ b/webroot/js/config.js @@ -1,7 +1,7 @@ // add more to the promises later. class Config { async init() { - const configFileLocation = "https://goth.land/config"; + const configFileLocation = "/config"; try { const response = await fetch(configFileLocation);