refactor(playback): simplify service files
This commit is contained in:
@@ -259,12 +259,11 @@ func (s *Service) setPlaybackBaseDataCache(key string, data playbackBaseData) {
|
||||
}
|
||||
|
||||
func (s *Service) resolveShowCached(ctx context.Context, malID int, titleCandidates []string) (string, string, error) {
|
||||
now := time.Now()
|
||||
|
||||
s.cacheMu.RLock()
|
||||
item, ok := s.showResolution[malID]
|
||||
s.cacheMu.RUnlock()
|
||||
|
||||
now := time.Now()
|
||||
if ok && now.Before(item.ExpiresAt) && strings.TrimSpace(item.ShowID) != "" {
|
||||
return item.ShowID, item.Title, nil
|
||||
}
|
||||
@@ -278,7 +277,7 @@ func (s *Service) resolveShowCached(ctx context.Context, malID int, titleCandida
|
||||
s.showResolution[malID] = showResolutionCacheItem{
|
||||
ShowID: showID,
|
||||
Title: resolvedTitle,
|
||||
ExpiresAt: time.Now().Add(showResolutionCacheTTL),
|
||||
ExpiresAt: now.Add(showResolutionCacheTTL),
|
||||
}
|
||||
s.cacheMu.Unlock()
|
||||
|
||||
@@ -347,7 +346,6 @@ func cloneStringSlice(items []string) []string {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cloned := make([]string, len(items))
|
||||
copy(cloned, items)
|
||||
return cloned
|
||||
@@ -357,7 +355,6 @@ func cloneModeSources(modeSources map[string]ModeSource) map[string]ModeSource {
|
||||
if len(modeSources) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cloned := make(map[string]ModeSource, len(modeSources))
|
||||
for mode, source := range modeSources {
|
||||
cloned[mode] = ModeSource{
|
||||
@@ -366,7 +363,6 @@ func cloneModeSources(modeSources map[string]ModeSource) map[string]ModeSource {
|
||||
Subtitles: cloneSubtitleItems(source.Subtitles),
|
||||
}
|
||||
}
|
||||
|
||||
return cloned
|
||||
}
|
||||
|
||||
@@ -374,7 +370,6 @@ func cloneSubtitleItems(items []SubtitleItem) []SubtitleItem {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cloned := make([]SubtitleItem, len(items))
|
||||
copy(cloned, items)
|
||||
return cloned
|
||||
@@ -384,7 +379,6 @@ func cloneSegments(segments []SkipSegment) []SkipSegment {
|
||||
if len(segments) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cloned := make([]SkipSegment, len(segments))
|
||||
copy(cloned, segments)
|
||||
return cloned
|
||||
|
||||
@@ -49,27 +49,33 @@ func (s *Service) ProxyStream(ctx context.Context, targetURL string, referer str
|
||||
}
|
||||
|
||||
func isM3U8(targetURL string, contentType string) bool {
|
||||
lowerURL := strings.ToLower(targetURL)
|
||||
lowerType := strings.ToLower(contentType)
|
||||
if strings.Contains(lowerURL, ".m3u8") {
|
||||
if strings.Contains(strings.ToLower(targetURL), ".m3u8") {
|
||||
return true
|
||||
}
|
||||
|
||||
lowerType := strings.ToLower(contentType)
|
||||
return strings.Contains(lowerType, "application/vnd.apple.mpegurl") || strings.Contains(lowerType, "application/x-mpegurl")
|
||||
}
|
||||
|
||||
var hopHeaders = map[string]struct{}{
|
||||
"connection": {},
|
||||
"transfer-encoding": {},
|
||||
"keep-alive": {},
|
||||
"proxy-authenticate": {},
|
||||
"proxy-authorization": {},
|
||||
"te": {},
|
||||
"trailers": {},
|
||||
"upgrade": {},
|
||||
}
|
||||
|
||||
func cloneHeaders(src http.Header) http.Header {
|
||||
dst := make(http.Header)
|
||||
for key, values := range src {
|
||||
lower := strings.ToLower(key)
|
||||
if lower == "connection" || lower == "transfer-encoding" || lower == "keep-alive" || lower == "proxy-authenticate" || lower == "proxy-authorization" || lower == "te" || lower == "trailers" || lower == "upgrade" {
|
||||
if _, ok := hopHeaders[strings.ToLower(key)]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, value := range values {
|
||||
dst.Add(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -189,16 +189,12 @@ func extractDigits(value string) string {
|
||||
|
||||
func normalizeSourceTypeFromProbe(source StreamSource, contentType string) StreamSource {
|
||||
lower := strings.ToLower(contentType)
|
||||
if strings.Contains(lower, "video/mp4") {
|
||||
switch {
|
||||
case strings.Contains(lower, "video/mp4"):
|
||||
source.Type = "mp4"
|
||||
return source
|
||||
}
|
||||
|
||||
if strings.Contains(lower, "mpegurl") {
|
||||
case strings.Contains(lower, "mpegurl"):
|
||||
source.Type = "m3u8"
|
||||
return source
|
||||
}
|
||||
|
||||
return source
|
||||
}
|
||||
|
||||
|
||||
@@ -122,12 +122,7 @@ func firstNonEmptyTitle(values []string) string {
|
||||
}
|
||||
|
||||
func normalizeMode(raw string) string {
|
||||
lower := strings.ToLower(strings.TrimSpace(raw))
|
||||
if lower == "sub" || lower == "dub" {
|
||||
return lower
|
||||
}
|
||||
|
||||
return lower
|
||||
return strings.ToLower(strings.TrimSpace(raw))
|
||||
}
|
||||
|
||||
func availableModes(modeSources map[string]ModeSource) []string {
|
||||
|
||||
@@ -60,19 +60,16 @@ func (s *Service) choosePlaybackSource(ctx context.Context, ranked []sourceScore
|
||||
return StreamSource{}, "", errors.New("no ranked sources available")
|
||||
}
|
||||
|
||||
embedCandidates := make([]StreamSource, 0)
|
||||
embedCandidates := make([]StreamSource, 0, len(ranked))
|
||||
for _, candidate := range ranked {
|
||||
source := candidate.source
|
||||
sourceType := strings.ToLower(source.Type)
|
||||
|
||||
switch sourceType {
|
||||
switch strings.ToLower(source.Type) {
|
||||
case "mp4", "m3u8":
|
||||
return source, "direct-media", nil
|
||||
case "embed":
|
||||
embedCandidates = append(embedCandidates, source)
|
||||
default:
|
||||
playable, contentType := s.probeDirectMedia(ctx, source)
|
||||
if playable {
|
||||
if playable, contentType := s.probeDirectMedia(ctx, source); playable {
|
||||
return normalizeSourceTypeFromProbe(source, contentType), "probed-media", nil
|
||||
}
|
||||
}
|
||||
@@ -101,19 +98,16 @@ func (s *Service) choosePlaybackSourceWithCache(
|
||||
return StreamSource{}, "", errors.New("no ranked sources available")
|
||||
}
|
||||
|
||||
embedCandidates := make([]StreamSource, 0)
|
||||
embedCandidates := make([]StreamSource, 0, len(ranked))
|
||||
for _, candidate := range ranked {
|
||||
source := candidate.source
|
||||
sourceType := strings.ToLower(source.Type)
|
||||
|
||||
switch sourceType {
|
||||
switch strings.ToLower(source.Type) {
|
||||
case "mp4", "m3u8":
|
||||
return source, "direct-media", nil
|
||||
case "embed":
|
||||
embedCandidates = append(embedCandidates, source)
|
||||
default:
|
||||
playable, contentType := s.probeDirectMediaCached(ctx, source, probeCache, probeCacheMu)
|
||||
if playable {
|
||||
if playable, contentType := s.probeDirectMediaCached(ctx, source, probeCache, probeCacheMu); playable {
|
||||
return normalizeSourceTypeFromProbe(source, contentType), "probed-media", nil
|
||||
}
|
||||
}
|
||||
@@ -208,10 +202,10 @@ func (s *Service) probeDirectMedia(ctx context.Context, source StreamSource) (bo
|
||||
}
|
||||
|
||||
func (s *Service) probeEmbedSource(ctx context.Context, source StreamSource) bool {
|
||||
probeCtx, cancel := context.WithTimeout(ctx, providerProbeTimeout)
|
||||
ctx, cancel := context.WithTimeout(ctx, providerProbeTimeout)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequestWithContext(probeCtx, http.MethodGet, source.URL, nil)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, source.URL, nil)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -237,7 +231,7 @@ func (s *Service) probeEmbedSource(ctx context.Context, source StreamSource) boo
|
||||
}
|
||||
|
||||
content := strings.ToLower(string(body))
|
||||
markers := []string{
|
||||
for _, marker := range []string{
|
||||
"file was deleted",
|
||||
"file has been deleted",
|
||||
"video was deleted",
|
||||
@@ -246,8 +240,7 @@ func (s *Service) probeEmbedSource(ctx context.Context, source StreamSource) boo
|
||||
"file not found",
|
||||
"this file does not exist",
|
||||
"resource unavailable",
|
||||
}
|
||||
for _, marker := range markers {
|
||||
} {
|
||||
if strings.Contains(content, marker) {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user