feat: enrich playlist album via file metadata (#307)

* feat: enrich playlist album via file metadata

* Refactor enrich command to use normalized source key

- Rename 'from' option to 'source' in command documentation- Update PlaylistEnrich function to correctly handle normalized source keys- Improve source key handling logic for album metadata extraction- Clarify source usage in the 'cliamp playlist enrich' command description

* feat: normalize song path

Replacing forward-slash instead of backslash to have less interference when sorting playlist by path

* feat: enrich elements year via file metadata
This commit is contained in:
RGR09
2026-08-18 18:11:54 +02:00
committed by GitHub
parent 78fcefa771
commit 7ce3dc47d5
3 changed files with 45 additions and 8 deletions
+37 -4
View File
@@ -607,7 +607,14 @@ func PlaylistBookmarks() error {
}
// PlaylistEnrich probes duration and derives album metadata for SSH tracks.
func PlaylistEnrich(name string) error {
func PlaylistEnrich(name string, source string) error {
src := normalizeSortKey(source)
switch src {
case "path", "metadata":
default:
return fmt.Errorf("unsupported source key %q (use path or metadata)", source)
}
prov, err := newProvider()
if err != nil {
return err
@@ -637,9 +644,23 @@ func PlaylistEnrich(name string) error {
}
if t.Album == "" {
if dir := albumFromPath(t.Path); dir != "" {
tracks[i].Album = dir
if src == "path" {
if dir := albumFromPath(t.Path); dir != "" {
tracks[i].Album = dir
changed = true
}
} else if src == "metadata" {
if album := probeAlbum(t.Path); album != "" {
tracks[i].Album = album
changed = true
}
}
}
if t.Year == 0 {
if year := probeYear(t.Path); year != 0 {
tracks[i].Year = year
changed = true
fmt.Fprintf(os.Stderr, " %s: %d\n", t.DisplayName(), year)
}
}
@@ -717,6 +738,16 @@ func parseProbeDuration(out []byte) int {
return int(dur)
}
func probeYear(path string) int {
t := playlist.TrackFromPath(path)
return t.Year
}
func probeAlbum(path string) string {
t := playlist.TrackFromPath(path)
return t.Album
}
func albumFromPath(path string) string {
if path == "" || playlist.IsURL(path) {
return ""
@@ -744,7 +775,9 @@ func collectLocalAudio(paths []string) ([]string, error) {
if err != nil {
return nil, fmt.Errorf("scanning %q: %w", p, err)
}
all = append(all, files...)
for _, f := range files {
all = append(all, strings.ReplaceAll(f, "\\", "/"))
}
}
return all, nil
}
+5 -2
View File
@@ -603,11 +603,14 @@ func playlistCommand() *cli.Command {
Name: "enrich",
Usage: "probe duration and album metadata for SSH tracks",
ArgsUsage: "\"Name\"",
Flags: []cli.Flag{
&cli.StringFlag{Name: "source", Usage: "source: metadata, path", Value: "path"},
},
Action: func(ctx context.Context, c *cli.Command) error {
if c.Args().Len() == 0 {
return fmt.Errorf("usage: cliamp playlist enrich \"Name\"")
return fmt.Errorf("usage: cliamp playlist enrich \"Name\" --source metadata")
}
return cmd.PlaylistEnrich(c.Args().First())
return cmd.PlaylistEnrich(c.Args().First(), c.String("source"))
},
},
},
+3 -2
View File
@@ -162,8 +162,9 @@ cliamp playlist export "Name" --format pls # export as PLS to stdout
cliamp playlist import mix.m3u --name "Name" # import local M3U/M3U8/PLS
cliamp playlist bookmark "Name" --index 3 # toggle bookmark flag
cliamp playlist bookmarks # list bookmarked tracks
cliamp playlist enrich "Name" # probe duration/album metadata
cliamp playlist delete "Name" # delete entire playlist
cliamp playlist enrich "Name" # probe duration/album
cliamp playlist enrich "Name" --source metadata # probe duration/album (forces to use the file's metadata as source)
cliamp playlist delete "Name" # delete entire playlist
```
Sort keys: `track`, `title`, `artist`, `album`, `artist+album`, `path`.