0.2.57 - Traliers bug fixes

This commit is contained in:
ponzischeme89
2026-08-12 13:08:53 +12:00
parent f2d052dbf6
commit 64f19aeef2
45 changed files with 1215 additions and 681 deletions
+43 -18
View File
@@ -14,7 +14,6 @@ import (
"github.com/ponzischeme89/memby/server/internal/cache"
"github.com/ponzischeme89/memby/server/internal/emby"
"github.com/ponzischeme89/memby/server/internal/store"
"github.com/ponzischeme89/memby/server/internal/trailer"
)
type remoteTrailer struct {
@@ -55,6 +54,7 @@ type trailerPlaybackResponse struct {
CandidateID string `json:"candidateId"`
Provider string `json:"provider"`
URL string `json:"url"`
SourceURL string `json:"sourceUrl,omitempty"`
Title string `json:"title"`
ItemID string `json:"itemId,omitempty"`
MediaSourceID string `json:"mediaSourceId,omitempty"`
@@ -62,6 +62,13 @@ type trailerPlaybackResponse struct {
PlayMethod string `json:"playMethod,omitempty"`
}
type trailerReportRequest struct {
CandidateID string `json:"candidateId"`
Provider string `json:"provider"`
Phase string `json:"phase"`
Reason string `json:"reason,omitempty"`
}
func (s *Server) handleTrailers(w http.ResponseWriter, r *http.Request, sess store.Session) {
itemID := strings.TrimSpace(r.PathValue("id"))
if itemID == "" {
@@ -107,37 +114,24 @@ func (s *Server) handleResolveTrailer(w http.ResponseWriter, r *http.Request, se
s.writeUpstreamError(r.Context(), w, err, "could not inspect trailers")
return
}
resolver := s.trailers
if resolver == nil {
resolver = trailer.New(nil)
}
for _, candidate := range s.preferredTrailerCandidates(r.Context(), sess, manifest) {
if excluded[candidate.ID] {
if candidate.SourceURL != "" {
resolver.Invalidate(trailer.Source{Provider: candidate.Provider, URL: candidate.SourceURL})
}
continue
}
if len(candidate.LocalItem) > 0 {
if resolved, resolveErr := s.resolveLocalTrailer(r.Context(), sess, manifest, candidate); resolveErr == nil {
s.rememberTrailerCandidate(r.Context(), sess, itemID, candidate.ID)
writeJSON(w, http.StatusOK, resolved)
return
}
continue
}
resolved, resolveErr := resolver.Resolve(r.Context(), trailer.Source{
Provider: candidate.Provider,
URL: candidate.SourceURL,
})
if resolveErr != nil {
continue
}
s.rememberTrailerCandidate(r.Context(), sess, itemID, candidate.ID)
// Remote pages are resolved on the television. YouTube signs direct media URLs for
// the resolving IP, so resolving here can make the URL unusable from the viewer's
// network and makes provider traffic appear to come from the gateway.
writeJSON(w, http.StatusOK, trailerPlaybackResponse{
CandidateID: candidate.ID,
Provider: candidate.Provider,
URL: resolved.URL,
SourceURL: candidate.SourceURL,
Title: trailerTitle(manifest.Title, candidate.Name),
PlayMethod: "DirectPlay",
})
@@ -146,6 +140,37 @@ func (s *Server) handleResolveTrailer(w http.ResponseWriter, r *http.Request, se
writeError(w, http.StatusNotFound, "no playable trailer is available")
}
func (s *Server) handleTrailerReport(w http.ResponseWriter, r *http.Request, sess store.Session) {
itemID := strings.TrimSpace(r.PathValue("id"))
var report trailerReportRequest
if itemID == "" || json.NewDecoder(http.MaxBytesReader(w, r.Body, 8<<10)).Decode(&report) != nil {
writeError(w, http.StatusBadRequest, "invalid trailer report")
return
}
report.CandidateID = strings.TrimSpace(report.CandidateID)
report.Provider = strings.ToLower(strings.TrimSpace(report.Provider))
report.Phase = strings.ToLower(strings.TrimSpace(report.Phase))
if report.CandidateID == "" || report.Provider == "" ||
(report.Phase != "started" && report.Phase != "failed" && report.Phase != "completed") {
writeError(w, http.StatusBadRequest, "invalid trailer report")
return
}
fields := []any{
"item_id", itemID,
"provider", report.Provider,
"candidate", report.CandidateID,
"source_ip", requestClientIP(r),
}
if reason := strings.TrimSpace(report.Reason); reason != "" {
fields = append(fields, "reason", reason)
}
s.loggerFor(r.Context()).Info("trailer playback "+report.Phase, fields...)
if report.Phase == "started" {
s.rememberTrailerCandidate(r.Context(), sess, itemID, report.CandidateID)
}
w.WriteHeader(http.StatusNoContent)
}
func (s *Server) preferredTrailerCandidates(
ctx context.Context,
sess store.Session,