767744a301
* refactor: rename core/transcode directory to core/stream * refactor: update all imports from core/transcode to core/stream * refactor: rename exported symbols to fit core/stream package name * refactor: simplify MediaStreamer interface to single NewStream method Remove the two-method interface (NewStream + DoStream) in favor of a single NewStream(ctx, mf, req) method. Callers are now responsible for fetching the MediaFile before calling NewStream. This removes the implicit DB lookup from the streamer, making it a pure streaming concern. * refactor: update all callers from DoStream to NewStream * chore: update wire_gen.go and stale comment for core/stream rename * refactor: update wire command to handle GO_BUILD_TAGS correctly Signed-off-by: Deluan <deluan@navidrome.org> * fix: distinguish not-found from internal errors in public stream handler * refactor: remove unused ID field from stream.Request * refactor: simplify ResolveRequestFromToken to receive *model.MediaFile Move MediaFile fetching responsibility to callers, making the method focused on token validation and request resolution. Remove ErrMediaNotFound (no longer produced). Update GetTranscodeStream handler to fetch the media file before calling ResolveRequestFromToken. * refactor: extend tokenTTL from 12 to 48 hours Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package stream
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
// containerAliasGroups maps each container alias to a canonical group name.
|
|
var containerAliasGroups = func() map[string]string {
|
|
groups := [][]string{
|
|
{"aac", "adts", "m4a", "mp4", "m4b", "m4p"},
|
|
{"mpeg", "mp3", "mp2"},
|
|
{"ogg", "oga", "opus"},
|
|
{"aif", "aiff"},
|
|
{"asf", "wma"},
|
|
{"mpc", "mpp"},
|
|
{"wv"},
|
|
}
|
|
m := make(map[string]string)
|
|
for _, g := range groups {
|
|
canonical := g[0]
|
|
for _, name := range g {
|
|
m[name] = canonical
|
|
}
|
|
}
|
|
return m
|
|
}()
|
|
|
|
// codecAliasGroups maps each codec alias to a canonical group name.
|
|
// Codecs within the same group are considered equivalent.
|
|
var codecAliasGroups = func() map[string]string {
|
|
groups := [][]string{
|
|
{"aac", "adts"},
|
|
{"ac3", "ac-3"},
|
|
{"eac3", "e-ac3", "e-ac-3", "eac-3"},
|
|
{"mpc7", "musepack7"},
|
|
{"mpc8", "musepack8"},
|
|
{"wma1", "wmav1"},
|
|
{"wma2", "wmav2"},
|
|
{"wmalossless", "wma9lossless"},
|
|
{"wmapro", "wma9pro"},
|
|
{"shn", "shorten"},
|
|
{"mp4als", "als"},
|
|
}
|
|
m := make(map[string]string)
|
|
for _, g := range groups {
|
|
for _, name := range g {
|
|
m[name] = g[0] // canonical = first entry
|
|
}
|
|
}
|
|
return m
|
|
}()
|
|
|
|
// matchesWithAliases checks if a value matches any entry in candidates,
|
|
// consulting the alias map for equivalent names.
|
|
func matchesWithAliases(value string, candidates []string, aliases map[string]string) bool {
|
|
value = strings.ToLower(value)
|
|
canonical := aliases[value]
|
|
for _, c := range candidates {
|
|
c = strings.ToLower(c)
|
|
if c == value {
|
|
return true
|
|
}
|
|
if canonical != "" && aliases[c] == canonical {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// matchesContainer checks if a file suffix matches any of the container names,
|
|
// including common aliases.
|
|
func matchesContainer(suffix string, containers []string) bool {
|
|
return matchesWithAliases(suffix, containers, containerAliasGroups)
|
|
}
|
|
|
|
// matchesCodec checks if a codec matches any of the codec names,
|
|
// including common aliases.
|
|
func matchesCodec(codec string, codecs []string) bool {
|
|
return matchesWithAliases(codec, codecs, codecAliasGroups)
|
|
}
|
|
|
|
func containsIgnoreCase(slice []string, s string) bool {
|
|
return slices.ContainsFunc(slice, func(item string) bool {
|
|
return strings.EqualFold(item, s)
|
|
})
|
|
}
|