2026-01-28 10:48:14 +00:00
|
|
|
package scanner
|
|
|
|
|
|
|
|
|
|
import (
|
2026-01-31 02:28:09 +00:00
|
|
|
"encoding/json"
|
2026-01-28 10:48:14 +00:00
|
|
|
"os"
|
2026-01-28 12:50:11 +00:00
|
|
|
"path"
|
2026-01-28 10:48:14 +00:00
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/pelletier/go-toml/v2"
|
2026-01-31 02:28:09 +00:00
|
|
|
ffmpeg_go "github.com/u2takey/ffmpeg-go"
|
2026-01-28 10:48:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
Category struct {
|
2026-01-30 14:14:54 +00:00
|
|
|
Name string `toml:"name"`
|
|
|
|
|
Type string `toml:"type" comment:"Valid types: gaming, other (default: other)"`
|
|
|
|
|
Url string `toml:"url"`
|
2026-01-28 10:48:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Metadata struct {
|
2026-01-30 14:14:54 +00:00
|
|
|
Title string `toml:"title"`
|
|
|
|
|
Part int `toml:"part"`
|
|
|
|
|
Date string `toml:"date"`
|
|
|
|
|
Tags []string `toml:"tags"`
|
|
|
|
|
FootageDir string `toml:"footage_dir"`
|
|
|
|
|
Uploaded bool `toml:"uploaded"`
|
|
|
|
|
Category *Category `toml:"category" comment:"(Optional) Category details, for additional credits."`
|
2026-01-28 10:48:14 +00:00
|
|
|
}
|
2026-01-31 02:28:09 +00:00
|
|
|
|
|
|
|
|
ffprobeFormat struct {
|
|
|
|
|
Duration float64 `json:"duration"`
|
|
|
|
|
Size int64 `json:"size"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ffprobeOutput struct {
|
|
|
|
|
Format ffprobeFormat `json:"format"`
|
|
|
|
|
}
|
2026-01-28 10:48:14 +00:00
|
|
|
)
|
|
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
const METADATA_FILENAME = "metadata.toml"
|
|
|
|
|
|
|
|
|
|
func ScanSegments(directory string, extension string) ([]string, error) {
|
2026-01-28 10:48:14 +00:00
|
|
|
entries, err := os.ReadDir(directory)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
files := []string{}
|
|
|
|
|
|
|
|
|
|
for _, item := range entries {
|
|
|
|
|
if item.IsDir() { continue }
|
2026-01-28 12:50:11 +00:00
|
|
|
if !strings.HasSuffix(item.Name(), "." + extension) { continue }
|
2026-01-30 14:14:54 +00:00
|
|
|
if strings.HasSuffix(item.Name(), "-fullvod." + extension) { continue }
|
2026-01-28 10:48:14 +00:00
|
|
|
files = append(files, item.Name())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return files, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-31 02:28:09 +00:00
|
|
|
func ProbeSegment(filename string) (*ffprobeOutput, error) {
|
|
|
|
|
out, err := ffmpeg_go.Probe(filename)
|
|
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
|
|
|
|
probe := ffprobeOutput{}
|
2026-01-31 03:22:17 +00:00
|
|
|
err = json.Unmarshal([]byte(out), &probe)
|
2026-01-31 02:28:09 +00:00
|
|
|
if err != nil { return nil, err }
|
|
|
|
|
|
|
|
|
|
return &probe, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
func ReadMetadata(directory string) (*Metadata, error) {
|
|
|
|
|
metadata := &Metadata{}
|
|
|
|
|
file, err := os.OpenFile(
|
|
|
|
|
path.Join(directory, METADATA_FILENAME),
|
|
|
|
|
os.O_RDONLY, os.ModePerm,
|
|
|
|
|
)
|
2026-01-30 19:23:35 +00:00
|
|
|
if err != nil { return nil, err }
|
2026-01-28 10:48:14 +00:00
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
err = toml.NewDecoder(file).Decode(metadata)
|
|
|
|
|
if err != nil { return nil, err }
|
2026-01-28 10:48:14 +00:00
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
return metadata, nil
|
2026-01-28 10:48:14 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
func WriteMetadata(directory string, metadata *Metadata) (error) {
|
|
|
|
|
file, err := os.OpenFile(
|
|
|
|
|
path.Join(directory, METADATA_FILENAME),
|
2026-01-30 14:14:54 +00:00
|
|
|
os.O_CREATE | os.O_RDWR, 0644,
|
2026-01-28 12:50:11 +00:00
|
|
|
)
|
|
|
|
|
if err != nil { return err }
|
|
|
|
|
|
|
|
|
|
err = toml.NewEncoder(file).Encode(metadata)
|
|
|
|
|
return err
|
2026-01-28 10:48:14 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-28 12:50:11 +00:00
|
|
|
func DefaultMetadata() *Metadata {
|
|
|
|
|
return &Metadata{
|
2026-01-28 10:48:14 +00:00
|
|
|
Title: "Untitled Stream",
|
|
|
|
|
Date: time.Now().Format("2006-01-02"),
|
|
|
|
|
Part: 0,
|
|
|
|
|
Category: &Category{
|
|
|
|
|
Name: "Something",
|
|
|
|
|
Type: "",
|
|
|
|
|
Url: "",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|