ghostream/main.go

134 lines
4.2 KiB
Go
Raw Normal View History

2020-09-28 15:36:40 +00:00
//go:generate pkger
2020-09-21 15:29:50 +00:00
package main
import (
2020-09-21 17:59:41 +00:00
"log"
2020-10-04 09:45:16 +00:00
"net"
2020-09-22 09:42:57 +00:00
"strings"
2020-09-21 17:59:41 +00:00
2020-09-22 09:42:57 +00:00
"github.com/spf13/viper"
"gitlab.crans.org/nounous/ghostream/auth"
2020-09-21 19:38:11 +00:00
"gitlab.crans.org/nounous/ghostream/internal/monitoring"
2020-09-30 13:07:36 +00:00
"gitlab.crans.org/nounous/ghostream/stream/forwarding"
2020-09-27 09:14:22 +00:00
"gitlab.crans.org/nounous/ghostream/stream/srt"
"gitlab.crans.org/nounous/ghostream/stream/webrtc"
2020-09-21 15:47:31 +00:00
"gitlab.crans.org/nounous/ghostream/web"
2020-09-21 15:29:50 +00:00
)
2020-09-22 09:42:57 +00:00
func loadConfiguration() {
// Load configuration from environnement variables
// Replace "." to "_" for nested structs
// e.g. GHOSTREAM_LDAP_URI will apply to Config.LDAP.URI
viper.SetEnvPrefix("ghostream")
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
viper.AutomaticEnv()
// Load configuration file if exists
2020-09-27 19:46:33 +00:00
viper.SetConfigName("ghostream.yml")
2020-09-22 09:42:57 +00:00
viper.SetConfigType("yaml")
viper.AddConfigPath("$HOME/.ghostream")
viper.AddConfigPath("/etc/ghostream")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found, ignore and use defaults
log.Print(err)
} else {
// Config file was found but another error was produced
log.Fatal(err)
}
} else {
// Config loaded
log.Printf("Using config file: %s", viper.ConfigFileUsed())
}
// Define configuration default values
2020-10-09 20:06:30 +00:00
viper.SetDefault("Auth.Enabled", true)
2020-09-22 14:39:06 +00:00
viper.SetDefault("Auth.Backend", "Basic")
2020-10-04 08:39:17 +00:00
viper.SetDefault("Auth.Basic.Credentials", map[string]string{
// Demo user with password "demo"
"demo": "$2b$15$LRnG3eIHFlYIguTxZOLH7eHwbQC/vqjnLq6nDFiHSUDKIU.f5/1H6",
})
2020-09-22 09:42:57 +00:00
viper.SetDefault("Auth.LDAP.URI", "ldap://127.0.0.1:389")
viper.SetDefault("Auth.LDAP.UserDn", "cn=users,dc=example,dc=com")
2020-10-04 15:56:03 +00:00
viper.SetDefault("Forwarding", make(map[string][]string))
2020-10-09 20:06:30 +00:00
viper.SetDefault("Monitoring.Enabled", true)
2020-09-22 09:42:57 +00:00
viper.SetDefault("Monitoring.ListenAddress", ":2112")
2020-10-09 20:06:30 +00:00
viper.SetDefault("Srt.Enabled", true)
2020-09-27 09:14:22 +00:00
viper.SetDefault("Srt.ListenAddress", ":9710")
viper.SetDefault("Srt.MaxClients", 64)
2020-10-09 20:06:30 +00:00
viper.SetDefault("Web.Enabled", true)
2020-10-04 15:56:03 +00:00
viper.SetDefault("Web.Favicon", "/static/img/favicon.svg")
viper.SetDefault("Web.Hostname", "localhost")
2020-09-27 19:55:22 +00:00
viper.SetDefault("Web.ListenAddress", ":8080")
2020-09-22 09:42:57 +00:00
viper.SetDefault("Web.Name", "Ghostream")
2020-10-04 15:56:03 +00:00
viper.SetDefault("Web.OneStreamPerDomain", false)
viper.SetDefault("Web.ViewersCounterRefreshPeriod", 20000)
2020-10-09 20:06:30 +00:00
viper.SetDefault("WebRTC.Enabled", true)
viper.SetDefault("WebRTC.MaxPortUDP", 10005)
2020-10-04 15:56:03 +00:00
viper.SetDefault("WebRTC.MinPortUDP", 10000)
2020-09-29 15:27:19 +00:00
viper.SetDefault("WebRTC.STUNServers", []string{"stun:stun.l.google.com:19302"})
// Copy STUN configuration to clients
viper.Set("Web.STUNServers", viper.Get("WebRTC.STUNServers"))
2020-10-04 09:45:16 +00:00
// Copy SRT server port to display it on web page
hostport := viper.GetString("Srt.ListenAddress")
_, srtPort, err := net.SplitHostPort(hostport)
if err != nil {
log.Fatalf("Failed to split host and port from %s", hostport)
}
viper.Set("Web.SRTServerPort", srtPort)
2020-09-22 09:42:57 +00:00
}
2020-09-21 15:29:50 +00:00
func main() {
2020-10-05 09:38:17 +00:00
// Configure logger
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
2020-09-21 17:59:41 +00:00
// Load configuration
2020-09-22 09:42:57 +00:00
loadConfiguration()
cfg := struct {
Auth auth.Options
2020-09-30 13:07:36 +00:00
Forwarding forwarding.Options
2020-09-22 09:42:57 +00:00
Monitoring monitoring.Options
2020-09-27 09:14:22 +00:00
Srt srt.Options
2020-09-22 09:42:57 +00:00
Web web.Options
WebRTC webrtc.Options
2020-09-22 09:42:57 +00:00
}{}
if err := viper.Unmarshal(&cfg); err != nil {
log.Fatalln("Failed to load settings", err)
2020-09-21 17:59:41 +00:00
}
2020-09-22 10:54:12 +00:00
// Init authentification
authBackend, err := auth.New(&cfg.Auth)
if err != nil {
log.Fatalln("Failed to load authentification backend:", err)
}
2020-10-09 20:06:30 +00:00
if authBackend != nil {
defer authBackend.Close()
}
2020-09-22 10:54:12 +00:00
2020-09-24 09:24:13 +00:00
// WebRTC session description channels
remoteSdpChan := make(chan struct {
StreamID string
RemoteDescription webrtc.SessionDescription
})
2020-09-24 09:24:13 +00:00
localSdpChan := make(chan webrtc.SessionDescription)
2020-09-21 19:05:45 +00:00
2020-10-04 16:22:10 +00:00
// SRT channel for forwarding and webrtc
forwardingChannel := make(chan srt.Packet, 65536)
2020-10-04 16:22:10 +00:00
webrtcChannel := make(chan srt.Packet, 65536)
// Start stream, web and monitoring server, and stream forwarding
go forwarding.Serve(forwardingChannel, cfg.Forwarding)
go monitoring.Serve(&cfg.Monitoring)
2020-10-04 16:22:10 +00:00
go srt.Serve(&cfg.Srt, authBackend, forwardingChannel, webrtcChannel)
2020-09-24 09:24:13 +00:00
go web.Serve(remoteSdpChan, localSdpChan, &cfg.Web)
2020-10-04 16:22:10 +00:00
go webrtc.Serve(remoteSdpChan, localSdpChan, webrtcChannel, &cfg.WebRTC)
2020-09-21 19:33:32 +00:00
2020-09-21 19:05:45 +00:00
// Wait for routines
select {}
2020-09-21 15:29:50 +00:00
}