package main import ( "bufio" "fmt" c "live-streamer/config" "live-streamer/logger" "live-streamer/server" "live-streamer/streamer" "live-streamer/utils" "os" "github.com/fsnotify/fsnotify" "go.uber.org/zap" ) var ( GlobalStreamer *streamer.Streamer log *zap.Logger config *c.Config ) func init() { config = c.GlobalConfig } func main() { // new logger log = logger.NewLogger(config.Log.Level) log.Debug("config", zap.Reflect("config", config)) // ffmpeg exist if !utils.HasFFmpeg() { log.Fatal("ffmpeg not found") } // new streamer var err error GlobalStreamer, err = streamer.NewStreamer(config.Output.RTMPServer, config.Output.StreamKey, config.VideoList, log, &streamer.Option{ FFmpegArgs: config.Play, ShowFFmpegOutput: config.Log.ShowFFmpegOutput, }) if err != nil { log.Fatal("new streamer error", zap.Error(err)) } // new server server.NewServer(config.Server.Addr, GlobalStreamer, log, &server.Option{ AuthToken: config.Server.Token, }) server.GlobalServer.Run() // coroutine go startWatcher() go inputHandler() // start streamer GlobalStreamer.Start() select {} } func inputHandler() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() switch line { case "list": fmt.Println(GlobalStreamer.GetVideoListPath()) case "index": fmt.Println(GlobalStreamer.GetCurrentIndex()) case "next": GlobalStreamer.Next() case "prev": GlobalStreamer.Prev() case "quit": GlobalStreamer.Close() case "current": fmt.Println(GlobalStreamer.GetCurrentVideoPath()) } } } func startWatcher() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal("failed to create watcher", zap.Error(err)) } defer watcher.Close() for _, item := range config.InputItems { if item.ItemType == "dir" { err = watcher.Add(item.Path) if err != nil { log.Fatal("failed to add dir to watcher", zap.Error(err)) } log.Info("watching dir", zap.String("path", item.Path)) } } if err != nil { log.Fatal("failed to start watcher", zap.Error(err)) } for { select { case event, ok := <-watcher.Events: if !ok { return } if event.Op&fsnotify.Create == fsnotify.Create { if utils.IsSupportedVideo(event.Name) { log.Info("new video added", zap.String("path", event.Name)) GlobalStreamer.Add(event.Name) } } if event.Op&fsnotify.Remove == fsnotify.Remove { log.Info("video removed", zap.String("path", event.Name)) GlobalStreamer.Remove(event.Name) } case err, ok := <-watcher.Errors: if !ok { return } log.Error("watcher error", zap.Error(err)) } } }