diff --git a/app/src/main/java/com/michatec/radio/collection/CollectionAdapter.kt b/app/src/main/java/com/michatec/radio/collection/CollectionAdapter.kt index 65eb287..78b0be7 100644 --- a/app/src/main/java/com/michatec/radio/collection/CollectionAdapter.kt +++ b/app/src/main/java/com/michatec/radio/collection/CollectionAdapter.kt @@ -471,18 +471,19 @@ class CollectionAdapter( } else if (holder is StationViewHolder) { // get station from position - collection.stations[holder.bindingAdapterPosition] + val station: Station = collection.stations[holder.bindingAdapterPosition] for (data in payloads) { when (data as Int) { Keys.HOLDER_UPDATE_COVER -> { - // todo implement + setStationImage(holder, station) + setStarredIcon(holder, station) } Keys.HOLDER_UPDATE_NAME -> { - // todo implement + setStationName(holder, station) } Keys.HOLDER_UPDATE_PLAYBACK_STATE -> { - // todo implement + setStationButtons(holder, station) } Keys.HOLDER_UPDATE_PLAYBACK_PROGRESS -> { // todo implement diff --git a/app/src/main/java/com/michatec/radio/helpers/AudioHelper.kt b/app/src/main/java/com/michatec/radio/helpers/AudioHelper.kt index 5968626..f2a932d 100644 --- a/app/src/main/java/com/michatec/radio/helpers/AudioHelper.kt +++ b/app/src/main/java/com/michatec/radio/helpers/AudioHelper.kt @@ -20,6 +20,8 @@ import androidx.media3.common.Metadata import androidx.media3.common.util.UnstableApi import androidx.media3.extractor.metadata.icy.IcyHeaders import androidx.media3.extractor.metadata.icy.IcyInfo +import androidx.media3.extractor.metadata.id3.Id3Frame +import androidx.media3.extractor.metadata.id3.TextInformationFrame import com.michatec.radio.Keys import kotlin.math.min @@ -37,28 +39,51 @@ object AudioHelper { /* Extract audio stream metadata */ @OptIn(UnstableApi::class) fun getMetadataString(metadata: Metadata): String { - var metadataString = String() + var title = "" + var artist = "" + var album = "" for (i in 0 until metadata.length()) { // extract IceCast metadata when (val entry = metadata.get(i)) { is IcyInfo -> { - metadataString = entry.title.toString() + title = entry.title.toString() } is IcyHeaders -> { Log.i(TAG, "icyHeaders:" + entry.name + " - " + entry.genre) } + is Id3Frame -> { + when (entry) { + is TextInformationFrame -> { + when (entry.id) { + "TIT2" -> title = entry.values.getOrNull(0) ?: "" // Title + "TPE1" -> artist = entry.values.getOrNull(0) ?: "" // Artist + "TALB" -> album = entry.values.getOrNull(0) ?: "" // Album + } + } + else -> { + Log.d(TAG, "Unhandled ID3 frame: ${entry.javaClass.simpleName}") + } + } + } + else -> { Log.w(TAG, "Unsupported metadata received (type = ${entry.javaClass.simpleName})") } } - // TODO implement HLS metadata extraction (Id3Frame / PrivFrame) - // https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/metadata/Metadata.Entry.html + } + // Build metadata string + var metadataString = title + if (artist.isNotEmpty() && title.isNotEmpty()) { + metadataString = "$artist - $title" + } + if (album.isNotEmpty() && metadataString.isNotEmpty()) { + metadataString += " ($album)" } // ensure a max length of the metadata string if (metadataString.isNotEmpty()) { - metadataString = metadataString.substring(0, min(metadataString.length, Keys.DEFAULT_MAX_LENGTH_OF_METADATA_ENTRY)) + metadataString = metadataString.take(min(metadataString.length, Keys.DEFAULT_MAX_LENGTH_OF_METADATA_ENTRY)) } return metadataString } diff --git a/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt b/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt index 73683ed..23819d7 100644 --- a/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt +++ b/app/src/main/java/com/michatec/radio/ui/LayoutHolder.kt @@ -14,6 +14,7 @@ package com.michatec.radio.ui +import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager import android.content.Context @@ -131,6 +132,7 @@ data class LayoutHolder(var rootView: View) { /* Updates the player views */ + @SuppressLint("DefaultLocale") fun updatePlayerViews(context: Context, station: Station, isPlaying: Boolean) { // set default metadata views, when playback has stopped @@ -164,12 +166,20 @@ data class LayoutHolder(var rootView: View) { // show only the codec when the bitrate is at "0" from radio-browser.info API station.codec } else { + val kiloBytesPerSecond = station.bitrate / 8F + val dataRateString = if (kiloBytesPerSecond >= 1000) { + String.format("%.2f mb/s", kiloBytesPerSecond / 1000F) + } else { + String.format("%.0f kb/s", kiloBytesPerSecond) + } // show the bitrate and codec if the result is available in the radio-browser.info API buildString { append(station.codec) append(" | ") append(station.bitrate) append("kbps") + append(" | ") + append(dataRateString) } } } else {