Git Repository
Mini Video Library
Mini Video Library scannt lokale Medienordner, verwaltet Metadaten und Vorschaubilder und streamt kompatible Videos direkt per HTTP an den Browser.
HTTPS
https://zanvex.de/git/mini-video-library.gitinternal/sidecar/subtitles.go
Zum Verzeichnispackage sidecar
import (
"bufio"
"bytes"
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
)
type Subtitle struct {
Path, Name, Language, Format string
Playable bool
}
var supported = map[string]bool{".srt": true, ".vtt": true, ".ass": true, ".ssa": true}
var languageAliases = map[string]string{"de": "de", "deu": "de", "ger": "de", "en": "en", "eng": "en", "ja": "ja", "jpn": "ja", "fr": "fr", "fra": "fr", "fre": "fr", "es": "es", "spa": "es"}
var timestamp = regexp.MustCompile(`(\d{2}:\d{2}:\d{2}),(\d{3})`)
func Find(videoPath string) ([]Subtitle, error) {
dir := filepath.Dir(videoPath)
base := strings.TrimSuffix(filepath.Base(videoPath), filepath.Ext(videoPath))
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var result []Subtitle
for _, entry := range entries {
if entry.IsDir() {
continue
}
ext := strings.ToLower(filepath.Ext(entry.Name()))
if !supported[ext] {
continue
}
stem := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
if stem != base && !strings.HasPrefix(stem, base+".") && !strings.HasPrefix(stem, base+"_") {
continue
}
language := "und"
parts := strings.FieldsFunc(strings.TrimPrefix(stem, base), func(r rune) bool { return r == '.' || r == '_' || r == '-' })
for _, part := range parts {
if value := languageAliases[strings.ToLower(part)]; value != "" {
language = value
break
}
}
result = append(result, Subtitle{Path: filepath.Join(dir, entry.Name()), Name: entry.Name(), Language: language, Format: strings.TrimPrefix(ext, "."), Playable: ext == ".srt" || ext == ".vtt"})
}
sort.Slice(result, func(i, j int) bool { return result[i].Name < result[j].Name })
return result, nil
}
func WebVTT(subtitle Subtitle) ([]byte, error) {
data, err := os.ReadFile(subtitle.Path)
if err != nil {
return nil, err
}
if strings.EqualFold(subtitle.Format, "vtt") {
return data, nil
}
if !strings.EqualFold(subtitle.Format, "srt") {
return nil, fmt.Errorf("subtitle format %s is not browser-playable", subtitle.Format)
}
var output bytes.Buffer
output.WriteString("WEBVTT\n\n")
scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
output.WriteString(timestamp.ReplaceAllString(scanner.Text(), "$1.$2"))
output.WriteByte('\n')
}
return output.Bytes(), scanner.Err()
}