live-streamer/main.go

129 lines
2.6 KiB
Go
Raw Normal View History

2024-10-22 16:39:10 -04:00
package main
import (
2024-10-23 17:06:19 -04:00
"bufio"
"fmt"
2024-10-24 04:43:06 -04:00
c "live-streamer/config"
"live-streamer/logger"
2024-10-23 10:47:37 -04:00
"live-streamer/server"
2024-10-22 16:39:10 -04:00
"live-streamer/streamer"
"live-streamer/utils"
2024-10-23 17:06:19 -04:00
"os"
2024-10-22 16:39:10 -04:00
"github.com/fsnotify/fsnotify"
"go.uber.org/zap"
)
var (
GlobalStreamer *streamer.Streamer
log *zap.Logger
config *c.Config
2024-10-22 16:39:10 -04:00
)
func init() {
config = c.GlobalConfig
}
2024-10-22 16:39:10 -04:00
func main() {
2024-10-29 05:11:14 -04:00
// new logger
log = logger.NewLogger(config.Log.Level)
2024-10-29 05:11:14 -04:00
log.Debug("config", zap.Reflect("config", config))
// ffmpeg exist
if !utils.HasFFmpeg() {
2024-10-22 16:39:10 -04:00
log.Fatal("ffmpeg not found")
}
2024-10-29 05:11:14 -04:00
// 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))
}
2024-10-29 05:11:14 -04:00
// new server
server.NewServer(config.Server.Addr, GlobalStreamer, log, &server.Option{
AuthToken: config.Server.Token,
})
server.GlobalServer.Run()
2024-10-29 05:11:14 -04:00
// coroutine
2024-10-22 16:39:10 -04:00
go startWatcher()
go inputHandler()
2024-10-29 05:11:14 -04:00
// start streamer
GlobalStreamer.Start()
select {}
2024-10-22 16:39:10 -04:00
}
func inputHandler() {
2024-10-23 17:06:19 -04:00
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
2024-10-24 04:43:06 -04:00
line := scanner.Text()
2024-10-23 17:06:19 -04:00
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())
}
}
}
2024-10-22 16:39:10 -04:00
func startWatcher() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal("failed to create watcher", zap.Error(err))
2024-10-22 16:39:10 -04:00
}
defer watcher.Close()
for _, item := range config.InputItems {
2024-10-22 16:39:10 -04:00
if item.ItemType == "dir" {
err = watcher.Add(item.Path)
if err != nil {
log.Fatal("failed to add dir to watcher", zap.Error(err))
2024-10-22 16:39:10 -04:00
}
log.Info("watching dir", zap.String("path", item.Path))
2024-10-22 16:39:10 -04:00
}
}
if err != nil {
log.Fatal("failed to start watcher", zap.Error(err))
2024-10-22 16:39:10 -04:00
}
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))
2024-10-22 16:39:10 -04:00
GlobalStreamer.Add(event.Name)
}
}
if event.Op&fsnotify.Remove == fsnotify.Remove {
log.Info("video removed", zap.String("path", event.Name))
2024-10-22 16:39:10 -04:00
GlobalStreamer.Remove(event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Error("watcher error", zap.Error(err))
2024-10-22 16:39:10 -04:00
}
}
}