Initial commit: sheepflix media streaming API

Go API for browsing/searching media files with ffprobe metadata,
token auth, and go-transcode integration for HLS streaming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Olive Vaughn 2026-08-26 00:08:01 -04:00
commit 31cd97e267
11 changed files with 631 additions and 0 deletions

View file

@ -0,0 +1,75 @@
package scanner
import (
"os"
"path/filepath"
"strings"
"time"
)
var videoExtensions = map[string]bool{
".mkv": true,
".mp4": true,
".avi": true,
".m4v": true,
".webm": true,
".ts": true,
".mov": true,
}
type MediaFile struct {
Path string `json:"-"`
RelPath string `json:"rel_path"`
Name string `json:"name"`
Size int64 `json:"size"`
ModTime time.Time `json:"mod_time"`
}
// DisplayName converts a filename into a human-readable display name.
func DisplayName(filename string) string {
name := strings.TrimSuffix(filename, filepath.Ext(filename))
name = strings.ReplaceAll(name, ".", " ")
name = strings.ReplaceAll(name, "_", " ")
return name
}
// Scan recursively walks rootDir and returns all video files found.
func Scan(rootDir string) ([]MediaFile, error) {
var files []MediaFile
err := filepath.WalkDir(rootDir, func(path string, d os.DirEntry, err error) error {
if err != nil {
return nil // skip inaccessible paths
}
if d.IsDir() {
return nil
}
ext := strings.ToLower(filepath.Ext(d.Name()))
if !videoExtensions[ext] {
return nil
}
info, err := d.Info()
if err != nil {
return nil
}
relPath, err := filepath.Rel(rootDir, path)
if err != nil {
return nil
}
files = append(files, MediaFile{
Path: path,
RelPath: relPath,
Name: DisplayName(d.Name()),
Size: info.Size(),
ModTime: info.ModTime(),
})
return nil
})
return files, err
}