diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-09 11:11:49 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-09 11:11:49 +0300 |
| commit | 8c32cd117abe79f4ee6cff3a950ffc35c95faeff (patch) | |
| tree | 5b63a4789351da4f2d9c1cd2e7007f67d43b3371 /internal/service/write.go | |
| parent | 59c8870061465142306e7a6e5d3fcb344686cfe9 (diff) | |
Refine media browsing and set covers
Diffstat (limited to 'internal/service/write.go')
| -rw-r--r-- | internal/service/write.go | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/internal/service/write.go b/internal/service/write.go index b5cd181..b23355a 100644 --- a/internal/service/write.go +++ b/internal/service/write.go @@ -149,7 +149,10 @@ func (s *writeService) RegenerateSetCover(ctx context.Context, setID int64, fold } prefix := filepath.ToSlash(strings.Trim(folder, "/")) - var candidates []model.Media + var artworkCandidates []model.Media + var videoCandidates []model.Media + var imageCandidates []model.Media + var thumbnailCandidates []model.Media for _, m := range media { if m.DeletedAt != nil { continue @@ -163,37 +166,81 @@ func (s *writeService) RegenerateSetCover(ctx context.Context, setID int64, fold if strings.Contains(suffix, "/") { continue } - } else if strings.Contains(rel, "/") { - continue } - if m.Type == model.MediaTypeVideo { - candidates = append(candidates, m) + switch { + case isFolderArtworkMedia(m): + artworkCandidates = append(artworkCandidates, m) + case m.Type == model.MediaTypeVideo: + videoCandidates = append(videoCandidates, m) + case m.Type == model.MediaTypeImage: + imageCandidates = append(imageCandidates, m) + case m.ThumbnailPath != "": + thumbnailCandidates = append(thumbnailCandidates, m) } } - if len(candidates) == 0 { - return errors.New("no video files available for cover") - } - - candidate := candidates[0] - if len(candidates) > 1 { - candidate = candidates[mrand.Intn(len(candidates))] - } baseDir := filepath.Join(s.mediaRoot, filepath.FromSlash(set.RootPath)) if prefix != "" { baseDir = filepath.Join(baseDir, filepath.FromSlash(prefix)) } coverPath := filepath.Join(filepath.Clean(baseDir), ".cover.jpg") - meta, err := s.prober.Probe(ctx, candidate.AbsPath) + + switch { + case len(artworkCandidates) > 0: + candidate := randomMedia(artworkCandidates) + if err := s.thumbGen.Generate(ctx, candidate.AbsPath, coverPath, 0); err != nil { + return fmt.Errorf("generate cover: %w", err) + } + case len(videoCandidates) > 0: + candidate := randomMedia(videoCandidates) + meta, err := s.prober.Probe(ctx, candidate.AbsPath) + if err != nil { + return fmt.Errorf("probe cover candidate: %w", err) + } + if err := s.thumbGen.Generate(ctx, candidate.AbsPath, coverPath, meta.Duration); err != nil { + return fmt.Errorf("generate cover: %w", err) + } + case len(imageCandidates) > 0: + candidate := randomMedia(imageCandidates) + if err := s.thumbGen.Generate(ctx, candidate.AbsPath, coverPath, 0); err != nil { + return fmt.Errorf("generate cover: %w", err) + } + case len(thumbnailCandidates) > 0: + candidate := randomMedia(thumbnailCandidates) + if err := copyFile(candidate.ThumbnailPath, coverPath); err != nil { + return fmt.Errorf("copy thumbnail cover: %w", err) + } + default: + return errors.New("no media files available for cover") + } + + return nil +} + +func randomMedia(media []model.Media) model.Media { + if len(media) == 1 { + return media[0] + } + return media[mrand.Intn(len(media))] +} + +func copyFile(src, dst string) error { + in, err := os.Open(src) if err != nil { - return fmt.Errorf("probe cover candidate: %w", err) + return err } + defer in.Close() - if err := s.thumbGen.Generate(ctx, candidate.AbsPath, coverPath, meta.Duration); err != nil { - return fmt.Errorf("generate cover: %w", err) + out, err := os.Create(dst) + if err != nil { + return err } - return nil + if _, err := io.Copy(out, in); err != nil { + _ = out.Close() + return err + } + return out.Close() } func (s *writeService) saveUploadedMedia(ctx context.Context, setID int64, path string, data io.Reader, size int64) (*model.Media, error) { |
