diff --git a/internal/features/playback/service_base.go b/internal/features/playback/service_base.go index 8217c4f..dcf77a2 100644 --- a/internal/features/playback/service_base.go +++ b/internal/features/playback/service_base.go @@ -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 diff --git a/internal/features/playback/service_proxy.go b/internal/features/playback/service_proxy.go index f8c3f85..cbd800d 100644 --- a/internal/features/playback/service_proxy.go +++ b/internal/features/playback/service_proxy.go @@ -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 } diff --git a/internal/features/playback/service_ranking.go b/internal/features/playback/service_ranking.go index 6435752..3e7b589 100644 --- a/internal/features/playback/service_ranking.go +++ b/internal/features/playback/service_ranking.go @@ -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 } diff --git a/internal/features/playback/service_resolution.go b/internal/features/playback/service_resolution.go index f166eea..0172c63 100644 --- a/internal/features/playback/service_resolution.go +++ b/internal/features/playback/service_resolution.go @@ -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 { diff --git a/internal/features/playback/service_sources.go b/internal/features/playback/service_sources.go index 8dcb8a1..904244a 100644 --- a/internal/features/playback/service_sources.go +++ b/internal/features/playback/service_sources.go @@ -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 }