Squash merge audio-player-component into main
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"yellowjacket/backend/metadata"
|
||||
"yellowjacket/backend/system"
|
||||
)
|
||||
|
||||
// saveCoverArt saves embedded cover art to the cache directory.
|
||||
// Returns the file path where the art was saved, or empty string if no picture data.
|
||||
func (l *Library) saveCoverArt(pic *metadata.PictureData) (string, error) {
|
||||
if pic == nil || len(pic.Data) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Get the data directory for storing cover art
|
||||
dataDir, err := system.GetUserDataDirPath()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not get user data directory: %w", err)
|
||||
}
|
||||
|
||||
coverDir := filepath.Join(dataDir, "covers")
|
||||
|
||||
// Ensure directory exists
|
||||
if err := os.MkdirAll(coverDir, 0o755); err != nil {
|
||||
return "", fmt.Errorf("could not create covers directory: %w", err)
|
||||
}
|
||||
|
||||
// Generate filename from content hash (deduplication)
|
||||
hash := sha256.Sum256(pic.Data)
|
||||
hashStr := hex.EncodeToString(hash[:8]) // First 8 bytes = 16 hex chars
|
||||
|
||||
ext := pic.Ext
|
||||
if ext == "" {
|
||||
// Determine extension from MIME type
|
||||
ext = extensionFromMIME(pic.MIMEType)
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%s.%s", hashStr, ext)
|
||||
filePath := filepath.Join(coverDir, filename)
|
||||
|
||||
// Skip if already exists (same content hash)
|
||||
if _, err := os.Stat(filePath); err == nil {
|
||||
l.logger.Debug("cover art already exists", "path", filePath)
|
||||
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// Write file
|
||||
if err := os.WriteFile(filePath, pic.Data, 0o644); err != nil {
|
||||
return "", fmt.Errorf("could not write cover art: %w", err)
|
||||
}
|
||||
|
||||
l.logger.Debug("saved cover art", "path", filePath, "size", len(pic.Data))
|
||||
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// extensionFromMIME returns a file extension for common image MIME types.
|
||||
func extensionFromMIME(mimeType string) string {
|
||||
switch mimeType {
|
||||
case "image/jpeg":
|
||||
return "jpg"
|
||||
case "image/png":
|
||||
return "png"
|
||||
case "image/gif":
|
||||
return "gif"
|
||||
case "image/webp":
|
||||
return "webp"
|
||||
case "image/bmp":
|
||||
return "bmp"
|
||||
default:
|
||||
return "jpg" // Default to jpg
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user