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

RemoteRenderer.kt

package dev.stave.domain.model

/**
 * A UPnP/DLNA MediaRenderer discovered on the LAN that advertises an AVTransport service.
 * Keyed by [udn] (Unique Device Name) for stability across IP changes — same idiom as
 * [MediaServer].
 *
 * Surfaced by [dev.stave.upnp.UpnpServiceHolder.renderers]. The renderer-mesh feature
 * uses this both as the picker's option list (Settings → Active renderer) and as the
 * target descriptor passed into the remote-renderer adapter when the user chooses a
 * non-local renderer to drive.
 */
data class RemoteRenderer(
    val udn: String,
    val friendlyName: String,
    val manufacturer: String?,
    val modelName: String?,
    val modelDescription: String?,
    val baseUrl: String,
    val iconUrl: String? = null,
) {
    /**
     * Detects sibling Earhorn instances on the LAN — i.e. other Earhorn renderers
     * broadcasting via the mesh-broadcast feature on desktop, phone, or TV. The
     * picker UI shows an "Earhorn" badge on these to distinguish them from generic
     * UPnP renderers (BubbleUPnP, Kazoo, JRiver, etc.).
     *
     * Recognition is by the manufacturer string Earhorn advertises in its UPnP
     * device description ("Faveat Software"), with a fallback to the model name
     * containing "Earhorn" in case the manufacturer string ever drifts.
     */
    val isEarhorn: Boolean
        get() = manufacturer?.contains("Faveat Software", ignoreCase = true) == true ||
            modelName?.contains("Earhorn", ignoreCase = true) == true
}