package types// ArtistRef is the minimal information a plugin returns for Navidrome to match an// artist against the library. It is a reference, not a full artist entity: it// carries only matching keys (name and optional internal/MusicBrainz IDs) plus a// few projection fields used when describing a track's participants, never// descriptive data such as biographies or images.type ArtistRef struct {// ID is the internal Navidrome artist ID (if known).ID string `json:"id,omitempty"`// Name is the artist name.Name string `json:"name"`// MBID is the MusicBrainz ID for the artist.MBID string `json:"mbid,omitempty"`// SortName is the artist name used for sorting (if known).SortName string `json:"sortName,omitempty"`// Role is the participation category (e.g. "artist", "composer", "performer").Role string `json:"role,omitempty"`// SubRole is a specialization within Role (e.g. the instrument for a performer).SubRole string `json:"subRole,omitempty"`}// SongRef is the minimal information exchanged between a plugin and Navidrome to// match a song. It is used both as input (a song Navidrome already has) and as// output (a song a plugin suggests, which may not be in the library yet). Unlike// Track, it is an abstract recording reference carrying only matching keys (IDs,// ISRC, and title/artist/album/duration) that Navidrome resolves to a library track.type SongRef struct {// ID is the internal Navidrome mediafile ID (if known).ID string `json:"id,omitempty"`// Name is the song name.Name string `json:"name"` // TODO: rename to Title to align with Track.Title and model.MediaFile.Title; kept as Name for now for compatibility.// MBID is the MusicBrainz ID for the song.MBID string `json:"mbid,omitempty"`// ISRC is the International Standard Recording Code for the song.ISRC string `json:"isrc,omitempty"`// Artist is the artist name.//// Deprecated: use Artists.Artist string `json:"artist,omitempty"`// ArtistMBID is the MusicBrainz artist ID.//// Deprecated: use Artists.ArtistMBID string `json:"artistMbid,omitempty"`// Artists is the full artist list; when set, takes precedence over Artist/ArtistMBID for matching.Artists []ArtistRef `json:"artists,omitempty"`// Album is the album name.Album string `json:"album,omitempty"`// AlbumMBID is the MusicBrainz release ID.AlbumMBID string `json:"albumMbid,omitempty"`// Duration is the song duration in seconds.//// Deprecated: use DurationMs, which carries millisecond precision. When// DurationMs is non-zero it takes precedence; Duration is kept only for// backwards compatibility with plugins that still send seconds.Duration float32 `json:"duration,omitempty"`// DurationMs is the song duration in milliseconds. It supersedes Duration// when non-zero.DurationMs uint32 `json:"durationMs,omitempty"`}// DurationInMs returns the song duration in milliseconds, preferring the// millisecond-precision DurationMs and falling back to the deprecated// seconds-based Duration. It returns 0 when neither is set, and clamps a// negative seconds value to 0 to avoid an unsigned-conversion wraparound.func (s SongRef) DurationInMs() uint32 {if s.DurationMs != 0 {return s.DurationMs}if s.Duration < 0 {return 0}return uint32(s.Duration * 1000)}// SetDuration sets the song duration from a value in seconds, populating both the// millisecond-precision DurationMs and the deprecated seconds-based Duration so// that plugins reading either field see a consistent value. Use this when// building a SongRef to send to a plugin.func (s *SongRef) SetDuration(seconds float32) {s.Duration = secondsif seconds < 0 {s.DurationMs = 0return}s.DurationMs = uint32(seconds * 1000)}