fix: fetch both sub and dub streams on watch page load
Previously the backend only fetched streams for the single requested mode (defaulting to sub), so modeSources never had a dub entry. The frontend's switchMode showed visual feedback but streamUrlForMode returned an empty string since no dub token existed. Now both modes are fetched and availableModes is derived from what actually resolved.
This commit is contained in:
@@ -126,19 +126,63 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SubtitleItem struct {
|
||||||
|
Lang string `json:"lang"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Referer string `json:"referer,omitempty"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModeSource struct {
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Referer string `json:"referer,omitempty"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Subtitles []SubtitleItem `json:"subtitles"`
|
||||||
|
Qualities []string `json:"qualities,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
modeSources := map[string]ModeSource{}
|
||||||
var result *domain.StreamResult
|
var result *domain.StreamResult
|
||||||
for _, p := range s.providers {
|
|
||||||
res, err := p.GetStreams(ctx, animeID, searchTitles, episode, mode)
|
for _, m := range []string{"sub", "dub"} {
|
||||||
if err == nil && res != nil {
|
for _, p := range s.providers {
|
||||||
result = res
|
res, err := p.GetStreams(ctx, animeID, searchTitles, episode, m)
|
||||||
|
if err != nil || res == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var subItems []SubtitleItem
|
||||||
|
for _, sub := range res.Subtitles {
|
||||||
|
subToken, _ := s.SignProxyToken(sub.URL, res.Referer, "subtitle")
|
||||||
|
subItems = append(subItems, SubtitleItem{
|
||||||
|
Lang: sub.Label,
|
||||||
|
Token: subToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
streamToken, _ := s.SignProxyToken(res.URL, res.Referer, "stream")
|
||||||
|
modeSources[m] = ModeSource{
|
||||||
|
URL: res.URL,
|
||||||
|
Referer: res.Referer,
|
||||||
|
Token: streamToken,
|
||||||
|
Subtitles: subItems,
|
||||||
|
}
|
||||||
|
|
||||||
|
if m == mode {
|
||||||
|
result = res
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if result == nil {
|
if len(modeSources) == 0 {
|
||||||
return nil, fmt.Errorf("no streams found")
|
return nil, fmt.Errorf("no streams found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if result == nil {
|
||||||
|
return nil, fmt.Errorf("no streams found for mode %s", mode)
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Get start time from progress
|
// 3. Get start time from progress
|
||||||
startTime := 0.0
|
startTime := 0.0
|
||||||
var watchlistStatus string
|
var watchlistStatus string
|
||||||
@@ -193,8 +237,6 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. Build provider data
|
// 5. Build provider data
|
||||||
// AllAnime currently returns one stream in result.URL
|
|
||||||
// We wrap it for the template
|
|
||||||
streams := []domain.ProviderStream{
|
streams := []domain.ProviderStream{
|
||||||
{
|
{
|
||||||
Name: "Primary",
|
Name: "Primary",
|
||||||
@@ -205,41 +247,6 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubtitleItem struct {
|
|
||||||
Lang string `json:"lang"`
|
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
Referer string `json:"referer,omitempty"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModeSource struct {
|
|
||||||
URL string `json:"url,omitempty"`
|
|
||||||
Referer string `json:"referer,omitempty"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
Subtitles []SubtitleItem `json:"subtitles"`
|
|
||||||
Qualities []string `json:"qualities,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var subtitleItems []SubtitleItem
|
|
||||||
for _, sub := range result.Subtitles {
|
|
||||||
subToken, _ := s.SignProxyToken(sub.URL, result.Referer, "subtitle")
|
|
||||||
subtitleItems = append(subtitleItems, SubtitleItem{
|
|
||||||
Lang: sub.Label,
|
|
||||||
Token: subToken,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
token, _ := s.SignProxyToken(result.URL, result.Referer, "stream")
|
|
||||||
|
|
||||||
modeSources := map[string]ModeSource{
|
|
||||||
mode: {
|
|
||||||
URL: result.URL,
|
|
||||||
Referer: result.Referer,
|
|
||||||
Token: token,
|
|
||||||
Subtitles: subtitleItems,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
go s.warmStreamURL(result.URL, result.Referer)
|
go s.warmStreamURL(result.URL, result.Referer)
|
||||||
|
|
||||||
// 6. Resolve relations/seasons
|
// 6. Resolve relations/seasons
|
||||||
@@ -281,7 +288,14 @@ func (s *playbackService) BuildWatchData(ctx context.Context, animeID int, title
|
|||||||
},
|
},
|
||||||
"ModeSources": modeSources,
|
"ModeSources": modeSources,
|
||||||
"InitialMode": mode,
|
"InitialMode": mode,
|
||||||
"AvailableModes": []string{"sub", "dub"},
|
"AvailableModes": func() []string {
|
||||||
|
var modes []string
|
||||||
|
for m := range modeSources {
|
||||||
|
modes = append(modes, m)
|
||||||
|
}
|
||||||
|
sort.Strings(modes)
|
||||||
|
return modes
|
||||||
|
}(),
|
||||||
"Segments": segments,
|
"Segments": segments,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user