2019-03-10 16:42:12 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
2019-03-26 19:30:52 +01:00
|
|
|
"fmt"
|
2019-03-10 16:42:12 +01:00
|
|
|
"net/http"
|
|
|
|
"os"
|
2019-03-21 21:20:50 +01:00
|
|
|
"os/signal"
|
2019-03-10 16:42:12 +01:00
|
|
|
|
|
|
|
"github.com/nareix/joy4/format"
|
|
|
|
"github.com/nareix/joy4/format/rtmp"
|
2019-03-24 23:51:39 +01:00
|
|
|
"github.com/zorchenhimer/MovieNight/common"
|
2019-03-10 16:42:12 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2019-03-21 21:20:50 +01:00
|
|
|
addr string
|
|
|
|
sKey string
|
2019-03-25 04:54:24 +01:00
|
|
|
stats = newStreamStats()
|
2019-03-10 16:42:12 +01:00
|
|
|
)
|
|
|
|
|
2019-03-26 16:44:19 +01:00
|
|
|
func setupSettings() error {
|
2019-03-25 04:54:24 +01:00
|
|
|
var err error
|
|
|
|
settings, err = LoadSettings("settings.json")
|
|
|
|
if err != nil {
|
2019-03-26 16:44:19 +01:00
|
|
|
return fmt.Errorf("Unable to load settings: %s", err)
|
2019-03-25 04:54:24 +01:00
|
|
|
}
|
|
|
|
if len(settings.StreamKey) == 0 {
|
2019-03-26 16:44:19 +01:00
|
|
|
return fmt.Errorf("Missing stream key is settings.json")
|
2019-03-25 04:54:24 +01:00
|
|
|
}
|
2019-03-21 21:20:50 +01:00
|
|
|
|
2019-03-25 04:54:24 +01:00
|
|
|
// Save admin password to file
|
|
|
|
if err = settings.Save(); err != nil {
|
2019-03-26 16:44:19 +01:00
|
|
|
return fmt.Errorf("Unable to save settings: %s", err)
|
2019-03-25 04:54:24 +01:00
|
|
|
}
|
2019-03-26 16:44:19 +01:00
|
|
|
|
|
|
|
return nil
|
2019-03-10 16:42:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2019-03-25 04:54:24 +01:00
|
|
|
flag.StringVar(&addr, "l", ":8089", "host:port of the MovieNight")
|
|
|
|
flag.StringVar(&sKey, "k", "", "Stream key, to protect your stream")
|
2019-03-10 16:42:12 +01:00
|
|
|
flag.Parse()
|
|
|
|
|
2019-03-25 04:54:24 +01:00
|
|
|
format.RegisterAll()
|
|
|
|
|
2019-03-26 16:44:19 +01:00
|
|
|
if err := setupSettings(); err != nil {
|
|
|
|
fmt.Printf("Error loading settings: %v\n", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2019-03-25 04:54:24 +01:00
|
|
|
|
2019-03-21 21:20:50 +01:00
|
|
|
exit := make(chan bool)
|
|
|
|
go handleInterrupt(exit)
|
|
|
|
|
|
|
|
// Load emotes before starting server.
|
|
|
|
var err error
|
|
|
|
if chat, err = newChatRoom(); err != nil {
|
2019-03-24 23:51:39 +01:00
|
|
|
common.LogErrorln(err)
|
2019-03-21 21:20:50 +01:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if addr != "" {
|
|
|
|
addr = settings.ListenAddress
|
|
|
|
}
|
|
|
|
|
|
|
|
// A stream key was passed on the command line. Use it, but don't save
|
|
|
|
// it over the stream key in the settings.json file.
|
|
|
|
if sKey != "" {
|
|
|
|
settings.SetTempKey(sKey)
|
|
|
|
}
|
|
|
|
|
2019-03-24 23:51:39 +01:00
|
|
|
common.LogInfoln("Stream key: ", settings.GetStreamKey())
|
|
|
|
common.LogInfoln("Admin password: ", settings.AdminPassword)
|
|
|
|
common.LogInfoln("Listen and serve ", addr)
|
2019-03-21 21:20:50 +01:00
|
|
|
|
|
|
|
go startServer()
|
2019-03-23 19:46:49 +01:00
|
|
|
go startRmtpServer()
|
2019-03-21 21:20:50 +01:00
|
|
|
|
|
|
|
<-exit
|
|
|
|
}
|
|
|
|
|
2019-03-23 19:46:49 +01:00
|
|
|
func startRmtpServer() {
|
2019-03-21 21:20:50 +01:00
|
|
|
server := &rtmp.Server{
|
|
|
|
HandlePlay: handlePlay,
|
|
|
|
HandlePublish: handlePublish,
|
|
|
|
}
|
|
|
|
err := server.ListenAndServe()
|
|
|
|
if err != nil {
|
2019-03-24 23:51:39 +01:00
|
|
|
// If the server cannot start, don't pretend we can continue.
|
|
|
|
panic("Error trying to start rtmp server: " + err.Error())
|
2019-03-21 21:20:50 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-10 16:42:12 +01:00
|
|
|
|
2019-03-21 21:20:50 +01:00
|
|
|
func startServer() {
|
2019-03-10 16:42:12 +01:00
|
|
|
// Chat websocket
|
|
|
|
http.HandleFunc("/ws", wsHandler)
|
2019-03-10 21:45:10 +01:00
|
|
|
http.HandleFunc("/static/js/", wsStaticFiles)
|
2019-03-16 15:13:30 +01:00
|
|
|
http.HandleFunc("/static/css/", wsStaticFiles)
|
2019-03-16 23:11:20 +01:00
|
|
|
http.HandleFunc("/static/img/", wsImages)
|
2019-03-20 15:59:28 +01:00
|
|
|
http.HandleFunc("/static/main.wasm", wsWasmFile)
|
2019-03-10 16:42:12 +01:00
|
|
|
http.HandleFunc("/emotes/", wsEmotes)
|
|
|
|
http.HandleFunc("/favicon.ico", wsStaticFiles)
|
2019-03-12 06:53:51 +01:00
|
|
|
http.HandleFunc("/chat", handleIndexTemplate)
|
|
|
|
http.HandleFunc("/video", handleIndexTemplate)
|
2019-03-16 21:15:45 +01:00
|
|
|
http.HandleFunc("/help", handleHelpTemplate)
|
2019-03-10 16:42:12 +01:00
|
|
|
|
2019-03-12 17:37:32 +01:00
|
|
|
http.HandleFunc("/", handleDefault)
|
2019-03-10 16:42:12 +01:00
|
|
|
|
2019-03-21 21:20:50 +01:00
|
|
|
err := http.ListenAndServe(addr, nil)
|
|
|
|
if err != nil {
|
2019-03-24 23:51:39 +01:00
|
|
|
// If the server cannot start, don't pretend we can continue.
|
|
|
|
panic("Error trying to start chat/http server: " + err.Error())
|
2019-03-10 16:42:12 +01:00
|
|
|
}
|
2019-03-21 21:20:50 +01:00
|
|
|
}
|
2019-03-10 16:42:12 +01:00
|
|
|
|
2019-03-21 21:20:50 +01:00
|
|
|
func handleInterrupt(exit chan bool) {
|
|
|
|
ch := make(chan os.Signal)
|
|
|
|
signal.Notify(ch, os.Interrupt)
|
|
|
|
<-ch
|
2019-03-24 23:51:39 +01:00
|
|
|
common.LogInfoln("Closing server")
|
2019-03-21 21:20:50 +01:00
|
|
|
if settings.StreamStats {
|
|
|
|
stats.Print()
|
2019-03-12 04:45:23 +01:00
|
|
|
}
|
2019-03-21 21:20:50 +01:00
|
|
|
exit <- true
|
2019-03-10 16:42:12 +01:00
|
|
|
}
|