147 lines
2.8 KiB
Go
147 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
|
|
"github.com/datarhei/joy4/format"
|
|
"github.com/datarhei/joy4/format/rtmp"
|
|
)
|
|
|
|
func init() {
|
|
format.RegisterAll()
|
|
}
|
|
|
|
type Config struct {
|
|
Addr string
|
|
App string
|
|
Token string
|
|
}
|
|
|
|
type Server interface {
|
|
ListenAndServe() error
|
|
ListenAndServeTLS(certFile, keyFile string) error
|
|
}
|
|
|
|
type server struct {
|
|
app string
|
|
token string
|
|
|
|
server *rtmp.Server
|
|
}
|
|
|
|
var _ Server = &server{}
|
|
|
|
func New(config Config) (Server, error) {
|
|
if len(config.App) == 0 {
|
|
config.App = "/"
|
|
}
|
|
|
|
s := &server{
|
|
app: config.App,
|
|
token: config.Token,
|
|
}
|
|
|
|
s.server = &rtmp.Server{
|
|
Addr: config.Addr,
|
|
}
|
|
|
|
s.server.HandlePlay = s.handlePlay
|
|
s.server.HandlePublish = s.handlePublish
|
|
|
|
rtmp.Debug = false
|
|
|
|
return s, nil
|
|
}
|
|
|
|
func (s *server) ListenAndServe() error {
|
|
return s.server.ListenAndServe()
|
|
}
|
|
|
|
func (s *server) ListenAndServeTLS(certFile, keyFile string) error {
|
|
return s.server.ListenAndServeTLS(certFile, keyFile)
|
|
}
|
|
|
|
func (s *server) log(who, action, path, message string, client net.Addr) {
|
|
fmt.Printf("%-7s %10s %s (%s) %s\n", who, action, path, client, message)
|
|
}
|
|
|
|
func (s *server) handlePlay(conn *rtmp.Conn) {
|
|
client := conn.NetConn().RemoteAddr()
|
|
|
|
s.log("PLAY", "INVALID", conn.URL.Path, "not supported", client)
|
|
conn.Close()
|
|
}
|
|
|
|
func (s *server) handlePublish(conn *rtmp.Conn) {
|
|
client := conn.NetConn().RemoteAddr()
|
|
|
|
streams, _ := conn.Streams()
|
|
|
|
if len(streams) == 0 {
|
|
s.log("PUBLISH", "INVALID", conn.URL.Path, "no streams available", client)
|
|
conn.Close()
|
|
return
|
|
}
|
|
|
|
s.log("PUBLISH", "START", conn.URL.Path, "", client)
|
|
|
|
for _, stream := range streams {
|
|
s.log("PUBLISH", "STREAM", conn.URL.Path, stream.Type().String(), client)
|
|
}
|
|
|
|
for {
|
|
if _, err := conn.ReadPacket(); err != nil {
|
|
if err != io.EOF {
|
|
s.log("PUBLISH", "ERROR", conn.URL.Path, err.Error(), client)
|
|
}
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
s.log("PUBLISH", "STOP", conn.URL.Path, "", client)
|
|
|
|
return
|
|
}
|
|
|
|
func main() {
|
|
var cert string
|
|
var key string
|
|
var help bool
|
|
var addr string
|
|
var app string
|
|
var token string
|
|
|
|
flag.StringVar(&cert, "cert", "", "Path to the certifacate file")
|
|
flag.StringVar(&key, "key", "", "Path to the key file")
|
|
flag.StringVar(&addr, "addr", ":1935", "Address to listen on")
|
|
flag.StringVar(&app, "app", "/", "RTMP app, should start with /")
|
|
flag.StringVar(&token, "token", "", "Token query string")
|
|
flag.BoolVar(&help, "h", false, "Show options")
|
|
|
|
flag.Parse()
|
|
|
|
config := Config{
|
|
Addr: addr,
|
|
App: app,
|
|
Token: token,
|
|
}
|
|
|
|
server, _ := New(config)
|
|
|
|
var err error
|
|
|
|
if len(cert) == 0 && len(key) == 0 {
|
|
fmt.Printf("Started RTMP server. Listening on %s\n", config.Addr)
|
|
err = server.ListenAndServe()
|
|
} else {
|
|
fmt.Printf("Started RTMPS server. Listening on %s\n", config.Addr)
|
|
err = server.ListenAndServeTLS(cert, key)
|
|
}
|
|
|
|
fmt.Printf("%s\n", err)
|
|
}
|