Files
seanime-docker/seanime-2.9.10/internal/library/playbackmanager/play_random_episode.go
2025-09-20 14:08:38 +01:00

99 lines
2.4 KiB
Go

package playbackmanager
import (
"context"
"fmt"
"seanime/internal/database/db_bridge"
"seanime/internal/library/anime"
"github.com/samber/lo"
)
type StartRandomVideoOptions struct {
UserAgent string
ClientId string
}
// StartRandomVideo starts a random video from the collection.
// Note that this might now be suited if the user has multiple seasons of the same anime.
func (pm *PlaybackManager) StartRandomVideo(opts *StartRandomVideoOptions) error {
pm.playlistHub.reset()
if err := pm.checkOrLoadAnimeCollection(); err != nil {
return err
}
animeCollection, err := pm.platform.GetAnimeCollection(context.Background(), false)
if err != nil {
return err
}
//
// Retrieve random episode
//
// Get lfs
lfs, _, err := db_bridge.GetLocalFiles(pm.Database)
if err != nil {
return fmt.Errorf("error getting local files: %s", err.Error())
}
// Create a local file wrapper
lfw := anime.NewLocalFileWrapper(lfs)
// Get entries (grouped by media id)
lfEntries := lfw.GetLocalEntries()
lfEntries = lo.Filter(lfEntries, func(e *anime.LocalFileWrapperEntry, _ int) bool {
return e.HasMainLocalFiles()
})
if len(lfEntries) == 0 {
return fmt.Errorf("no playable media found")
}
continueLfs := make([]*anime.LocalFile, 0)
otherLfs := make([]*anime.LocalFile, 0)
for _, e := range lfEntries {
anilistEntry, ok := animeCollection.GetListEntryFromAnimeId(e.GetMediaId())
if !ok {
continue
}
progress := 0
if anilistEntry.Progress != nil {
progress = *anilistEntry.Progress
}
if anilistEntry.Status == nil || *anilistEntry.Status == "COMPLETED" {
continue
}
firstUnwatchedFile, found := e.GetFirstUnwatchedLocalFiles(progress)
if !found {
continue
}
if *anilistEntry.Status == "CURRENT" || *anilistEntry.Status == "REPEATING" {
continueLfs = append(continueLfs, firstUnwatchedFile)
} else {
otherLfs = append(otherLfs, firstUnwatchedFile)
}
}
if len(continueLfs) == 0 && len(otherLfs) == 0 {
return fmt.Errorf("no playable file found")
}
lfs = append(continueLfs, otherLfs...)
// only choose from continueLfs if there are more than 8 episodes
if len(continueLfs) > 8 {
lfs = continueLfs
}
lfs = lo.Shuffle(lfs)
err = pm.StartPlayingUsingMediaPlayer(&StartPlayingOptions{
Payload: lfs[0].GetPath(),
UserAgent: opts.UserAgent,
ClientId: opts.ClientId,
})
if err != nil {
return err
}
return nil
}