Git Repository
miniaudiolib
miniaudiolib scannt lokale Musik- und Hörbuchordner, liest Audio-Metadaten und Cover, verwaltet Favoriten und Playlists und streamt Titel direkt an den Browser.
HTTPS
https://zanvex.de/git/miniaudiolib.gitcmd/miniaudiolib/main.go
Zum Verzeichnispackage main
import (
"context"
"flag"
"io"
"log/slog"
"miniaudiolib/internal/config"
"miniaudiolib/internal/logging"
"miniaudiolib/internal/musicdb"
"miniaudiolib/internal/musiclib"
"miniaudiolib/internal/musicscanner"
"miniaudiolib/internal/musicweb"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
configPath := flag.String("config", "config.toml", "path to configuration")
scanOnly := flag.Bool("scan", false, "scan once and exit")
flag.Parse()
logs := logging.NewStore(1000)
out := io.Writer(os.Stdout)
if f, e := logging.NewRotatingWriter("data/logs/miniaudiolib.log", 10<<20); e == nil {
defer f.Close()
out = io.MultiWriter(out, f)
}
logger := slog.New(logging.NewHandler(slog.NewTextHandler(out, nil), logs))
cfg, e := config.Load(*configPath)
if e != nil {
logger.Error("load config", "error", e)
os.Exit(1)
}
db, e := musicdb.Open(cfg.DatabasePath)
if e != nil {
logger.Error("open database", "error", e)
os.Exit(1)
}
defer db.Close()
scan := musicscanner.New(db, cfg, logger)
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
if *scanOnly {
if e = scan.Run(ctx); e != nil && e != context.Canceled {
logger.Error("scan", "error", e)
os.Exit(1)
}
return
}
lib := musiclib.New(db)
handler, e := musicweb.New(lib, db, scan, cfg, *configPath, logger)
if e != nil {
logger.Error("web", "error", e)
os.Exit(1)
}
srv := &http.Server{Addr: cfg.ListenAddress, Handler: handler, ReadHeaderTimeout: 10 * time.Second}
go func() {
logger.Info("music library ready", "url", "http://"+cfg.ListenAddress)
if e := srv.ListenAndServe(); e != nil && e != http.ErrServerClosed {
logger.Error("server", "error", e)
cancel()
}
}()
<-ctx.Done()
shutdown, stop := context.WithTimeout(context.Background(), 10*time.Second)
defer stop()
_ = srv.Shutdown(shutdown)
}