EARHORNMUSIC UPnP · Android TV · Phones · Android Auto · GNU/Linux
Release 0.5.0

DidlItem.kt

Each line, with the release that last changed it.

0.5.01package dev.stave.domain.model
2
3import kotlin.time.Duration
4
5/**
6 * A single entry returned by a ContentDirectory Browse() call.
7 * Either a Container (navigable) or a Track (playable) — images/playlists come later.
8 *
9 * The [extras] map preserves non-standard properties MinimServer exposes via
10 * upnp:userAnnotation — Work, Group, DiscSubtitle, etc. — so the UI can render them
11 * without the parser having to know the full list ahead of time.
12 */
13sealed class DidlItem {
14 abstract val id: String
15 abstract val parentId: String
16 abstract val title: String
17 abstract val extras: Map<String, String>
18
19 data class Container(
20 override val id: String,
21 override val parentId: String,
22 override val title: String,
23 val childCount: Int?,
24 val albumArtUri: String?,
25 val upnpClass: String,
26 /** Album artist / creator for album containers — null for generic folders. */
27 val artist: String?,
28 /** True for MinimServer's synthetic entries: `>> Show All`, `[folder view]`, disc headings. */
29 val isSynthetic: Boolean,
30 override val extras: Map<String, String> = emptyMap(),
31 ) : DidlItem() {
32 val isAlbum: Boolean get() = upnpClass.contains("musicAlbum", ignoreCase = true)
33
34 /** True for genre containers (`object.container.genre.musicGenre` and
35 * friends). Gates the "Play 42 random <Genre> tracks" context action;
36 * mirrors the Android `DidlItem.Container.isGenre` helper. */
37 val isGenre: Boolean get() = upnpClass.contains("genre", ignoreCase = true)
38 }
39
40 data class Track(
41 override val id: String,
42 override val parentId: String,
43 override val title: String,
44 val artist: String?,
45 val albumArtist: String?,
46 val album: String?,
47 val composer: String?,
48 val genre: String?,
49 val date: String?,
50 val trackNumber: Int?,
51 val discNumber: Int?,
52 val duration: Duration?,
53 val albumArtUri: String?,
54 val resourceUrl: String,
55 val mimeType: String?,
56 val sampleFrequency: Int?,
57 val bitsPerSample: Int?,
58 val channels: Int?,
59 val bitrate: Int?,
60 val size: Long?,
61 override val extras: Map<String, String> = emptyMap(),
62 ) : DidlItem() {
63 val isLossless: Boolean get() = mimeType?.let {
64 it.contains("flac") || it.contains("wav") || it.contains("alac") || it.contains("aiff")
65 } ?: false
66 }
67}