improved library scan speeds, added library manager component

-libraries tab now opens a library manager
-choose library directory, manually soft scan and rescan
-batched db queues
-mp3 header-based duration extraction
This commit is contained in:
2026-02-19 10:17:09 -05:00
parent 8c013d4179
commit 81793975b4
36 changed files with 2350 additions and 179 deletions
+46
View File
@@ -2,6 +2,7 @@ package metadata
import (
"fmt"
"io"
"os"
)
@@ -50,3 +51,48 @@ func GetTrackLengthMillis(path string) (int64, error) {
return lengthMillis, nil
}
// ExtractAllMetadata opens the file once and extracts both tags and duration.
// This avoids the overhead of opening the file twice when both are needed.
// If skipDuration is true, only tags are extracted and lengthMillis is 0.
func ExtractAllMetadata(
path string,
skipDuration bool,
) (*TrackMetadata, int64, error) {
f, err := os.Open(path)
if err != nil {
return nil, 0, fmt.Errorf(
"could not open file: %w", err,
)
}
defer func() { _ = f.Close() }()
// Extract tags first (reads only headers, fast).
tags, err := ExtractTagsFromReader(f)
if err != nil {
return nil, 0, fmt.Errorf(
"could not extract tags from %s: %w", path, err,
)
}
if skipDuration {
return tags, 0, nil
}
// Seek back to the beginning for duration extraction.
if _, err := f.Seek(0, io.SeekStart); err != nil {
return tags, 0, fmt.Errorf(
"could not seek file for duration: %w", err,
)
}
lengthMillis, err := getTrackDuration(f)
if err != nil {
return tags, 0, fmt.Errorf(
"error getting duration for %s: %w", path, err,
)
}
return tags, lengthMillis, nil
}