- Layout Changes

- HLS media extraction
This commit is contained in:
Michatec
2026-01-25 16:08:22 +01:00
parent 0adb906438
commit d3dfcb98f9
3 changed files with 45 additions and 9 deletions

View File

@@ -471,18 +471,19 @@ class CollectionAdapter(
} else if (holder is StationViewHolder) { } else if (holder is StationViewHolder) {
// get station from position // get station from position
collection.stations[holder.bindingAdapterPosition] val station: Station = collection.stations[holder.bindingAdapterPosition]
for (data in payloads) { for (data in payloads) {
when (data as Int) { when (data as Int) {
Keys.HOLDER_UPDATE_COVER -> { Keys.HOLDER_UPDATE_COVER -> {
// todo implement setStationImage(holder, station)
setStarredIcon(holder, station)
} }
Keys.HOLDER_UPDATE_NAME -> { Keys.HOLDER_UPDATE_NAME -> {
// todo implement setStationName(holder, station)
} }
Keys.HOLDER_UPDATE_PLAYBACK_STATE -> { Keys.HOLDER_UPDATE_PLAYBACK_STATE -> {
// todo implement setStationButtons(holder, station)
} }
Keys.HOLDER_UPDATE_PLAYBACK_PROGRESS -> { Keys.HOLDER_UPDATE_PLAYBACK_PROGRESS -> {
// todo implement // todo implement

View File

@@ -20,6 +20,8 @@ import androidx.media3.common.Metadata
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.extractor.metadata.icy.IcyHeaders import androidx.media3.extractor.metadata.icy.IcyHeaders
import androidx.media3.extractor.metadata.icy.IcyInfo 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 com.michatec.radio.Keys
import kotlin.math.min import kotlin.math.min
@@ -37,28 +39,51 @@ object AudioHelper {
/* Extract audio stream metadata */ /* Extract audio stream metadata */
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
fun getMetadataString(metadata: Metadata): String { fun getMetadataString(metadata: Metadata): String {
var metadataString = String() var title = ""
var artist = ""
var album = ""
for (i in 0 until metadata.length()) { for (i in 0 until metadata.length()) {
// extract IceCast metadata // extract IceCast metadata
when (val entry = metadata.get(i)) { when (val entry = metadata.get(i)) {
is IcyInfo -> { is IcyInfo -> {
metadataString = entry.title.toString() title = entry.title.toString()
} }
is IcyHeaders -> { is IcyHeaders -> {
Log.i(TAG, "icyHeaders:" + entry.name + " - " + entry.genre) 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 -> { else -> {
Log.w(TAG, "Unsupported metadata received (type = ${entry.javaClass.simpleName})") 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 // ensure a max length of the metadata string
if (metadataString.isNotEmpty()) { 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 return metadataString
} }

View File

@@ -14,6 +14,7 @@
package com.michatec.radio.ui package com.michatec.radio.ui
import android.annotation.SuppressLint
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
@@ -131,6 +132,7 @@ data class LayoutHolder(var rootView: View) {
/* Updates the player views */ /* Updates the player views */
@SuppressLint("DefaultLocale")
fun updatePlayerViews(context: Context, station: Station, isPlaying: Boolean) { fun updatePlayerViews(context: Context, station: Station, isPlaying: Boolean) {
// set default metadata views, when playback has stopped // 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 // show only the codec when the bitrate is at "0" from radio-browser.info API
station.codec station.codec
} else { } 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 // show the bitrate and codec if the result is available in the radio-browser.info API
buildString { buildString {
append(station.codec) append(station.codec)
append(" | ") append(" | ")
append(station.bitrate) append(station.bitrate)
append("kbps") append("kbps")
append(" | ")
append(dataRateString)
} }
} }
} else { } else {