Twelve: Add picture type to thumbnail and add artwork data to MediaItem
Change-Id: I6a0fe3aacda771e3ec28c9c256acf86dbc38dbef
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
index 3bdadd8..73dc995 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
@@ -70,7 +70,7 @@
uri, Size(512, 512), null
)
}.getOrNull()?.let {
- Thumbnail(bitmap = it)
+ Thumbnail(bitmap = it, type = Thumbnail.Type.FRONT_COVER)
}
Album(
@@ -96,7 +96,7 @@
uri, Size(512, 512), null
)
}.getOrNull()?.let {
- Thumbnail(bitmap = it)
+ Thumbnail(bitmap = it, type = Thumbnail.Type.BAND_ARTIST_LOGO)
}
Artist(
diff --git a/app/src/main/java/org/lineageos/twelve/ext/Bitmap.kt b/app/src/main/java/org/lineageos/twelve/ext/Bitmap.kt
new file mode 100644
index 0000000..5e5f846
--- /dev/null
+++ b/app/src/main/java/org/lineageos/twelve/ext/Bitmap.kt
@@ -0,0 +1,13 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The LineageOS Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.twelve.ext
+
+import android.graphics.Bitmap
+import java.nio.ByteBuffer
+
+fun Bitmap.toByteArray(): ByteArray = ByteBuffer.allocate(rowBytes * height).apply {
+ copyPixelsToBuffer(this)
+}.array()
diff --git a/app/src/main/java/org/lineageos/twelve/ext/MediaItem.kt b/app/src/main/java/org/lineageos/twelve/ext/MediaItem.kt
index 9f513b1..ce8276a 100644
--- a/app/src/main/java/org/lineageos/twelve/ext/MediaItem.kt
+++ b/app/src/main/java/org/lineageos/twelve/ext/MediaItem.kt
@@ -20,7 +20,9 @@
genre: String? = null,
sourceUri: Uri? = null,
mimeType: String? = null,
- imageUri: Uri? = null
+ artworkData: ByteArray? = null,
+ artworkType: @MediaMetadata.PictureType Int? = null,
+ artworkUri: Uri? = null,
): MediaItem {
val metadata =
MediaMetadata.Builder()
@@ -30,7 +32,8 @@
.setGenre(genre)
.setIsBrowsable(isBrowsable)
.setIsPlayable(isPlayable)
- .setArtworkUri(imageUri)
+ .setArtworkData(artworkData, artworkType)
+ .setArtworkUri(artworkUri)
.setMediaType(mediaType)
.build()
diff --git a/app/src/main/java/org/lineageos/twelve/models/Album.kt b/app/src/main/java/org/lineageos/twelve/models/Album.kt
index ab9147e..03545e6 100644
--- a/app/src/main/java/org/lineageos/twelve/models/Album.kt
+++ b/app/src/main/java/org/lineageos/twelve/models/Album.kt
@@ -8,6 +8,7 @@
import android.net.Uri
import androidx.media3.common.MediaMetadata
import org.lineageos.twelve.ext.buildMediaItem
+import org.lineageos.twelve.ext.toByteArray
/**
* An album.
@@ -43,6 +44,9 @@
isBrowsable = true,
mediaType = MediaMetadata.MEDIA_TYPE_ALBUM,
sourceUri = uri,
+ artworkData = thumbnail?.bitmap?.toByteArray(),
+ artworkType = thumbnail?.type?.media3Value,
+ artworkUri = thumbnail?.uri,
)
companion object {
diff --git a/app/src/main/java/org/lineageos/twelve/models/Artist.kt b/app/src/main/java/org/lineageos/twelve/models/Artist.kt
index 36c8af3..d195887 100644
--- a/app/src/main/java/org/lineageos/twelve/models/Artist.kt
+++ b/app/src/main/java/org/lineageos/twelve/models/Artist.kt
@@ -8,6 +8,7 @@
import android.net.Uri
import androidx.media3.common.MediaMetadata
import org.lineageos.twelve.ext.buildMediaItem
+import org.lineageos.twelve.ext.toByteArray
/**
* An artist.
@@ -34,6 +35,9 @@
isBrowsable = true,
mediaType = MediaMetadata.MEDIA_TYPE_ARTIST,
sourceUri = uri,
+ artworkData = thumbnail?.bitmap?.toByteArray(),
+ artworkType = thumbnail?.type?.media3Value,
+ artworkUri = thumbnail?.uri,
)
companion object {
diff --git a/app/src/main/java/org/lineageos/twelve/models/Thumbnail.kt b/app/src/main/java/org/lineageos/twelve/models/Thumbnail.kt
index 8cb272c..e7612e7 100644
--- a/app/src/main/java/org/lineageos/twelve/models/Thumbnail.kt
+++ b/app/src/main/java/org/lineageos/twelve/models/Thumbnail.kt
@@ -7,6 +7,7 @@
import android.graphics.Bitmap
import android.net.Uri
+import androidx.media3.common.MediaMetadata
/**
* A thumbnail for a media item. It can be a URI or a bitmap. Both can be defined, in that case the
@@ -14,11 +15,130 @@
*
* @param uri The URI of the thumbnail.
* @param bitmap The bitmap of the thumbnail.
+ * @param type the type of the thumbnail.
*/
data class Thumbnail(
val uri: Uri? = null,
val bitmap: Bitmap? = null,
+ val type: Type = Type.OTHER,
) : Comparable<Thumbnail> {
+ /**
+ * ID3-like picture types.
+ */
+ enum class Type(val media3Value: @MediaMetadata.PictureType Int) {
+ /**
+ * Other.
+ */
+ OTHER(MediaMetadata.PICTURE_TYPE_OTHER),
+
+ /**
+ * 32x32 pixels 'file icon' (PNG only).
+ */
+ FILE_ICON(MediaMetadata.PICTURE_TYPE_FILE_ICON),
+
+ /**
+ * Other file icon.
+ */
+ FILE_ICON_OTHER(MediaMetadata.PICTURE_TYPE_FILE_ICON_OTHER),
+
+ /**
+ * Cover (front).
+ */
+ FRONT_COVER(MediaMetadata.PICTURE_TYPE_FRONT_COVER),
+
+ /**
+ * Cover (back).
+ */
+ BACK_COVER(MediaMetadata.PICTURE_TYPE_BACK_COVER),
+
+ /**
+ * Leaflet page.
+ */
+ LEAFLET_PAGE(MediaMetadata.PICTURE_TYPE_LEAFLET_PAGE),
+
+ /**
+ * Media (e.g. label side of CD).
+ */
+ MEDIA(MediaMetadata.PICTURE_TYPE_MEDIA),
+
+ /**
+ * Lead artist/lead performer/soloist.
+ */
+ LEAD_ARTIST_PERFORMER(MediaMetadata.PICTURE_TYPE_LEAD_ARTIST_PERFORMER),
+
+ /**
+ * Artist/performer.
+ */
+ ARTIST_PERFORMER(MediaMetadata.PICTURE_TYPE_ARTIST_PERFORMER),
+
+ /**
+ * Conductor.
+ */
+ CONDUCTOR(MediaMetadata.PICTURE_TYPE_CONDUCTOR),
+
+ /**
+ * Band/Orchestra.
+ */
+ BAND_ORCHESTRA(MediaMetadata.PICTURE_TYPE_BAND_ORCHESTRA),
+
+ /**
+ * Composer.
+ */
+ COMPOSER(MediaMetadata.PICTURE_TYPE_COMPOSER),
+
+ /**
+ * Lyricist/text writer.
+ */
+ LYRICIST(MediaMetadata.PICTURE_TYPE_LYRICIST),
+
+ /**
+ * Recording Location.
+ */
+ RECORDING_LOCATION(MediaMetadata.PICTURE_TYPE_RECORDING_LOCATION),
+
+ /**
+ * During recording.
+ */
+ DURING_RECORDING(MediaMetadata.PICTURE_TYPE_DURING_RECORDING),
+
+ /**
+ * During performance.
+ */
+ DURING_PERFORMANCE(MediaMetadata.PICTURE_TYPE_DURING_PERFORMANCE),
+
+ /**
+ * Movie/video screen capture.
+ */
+ MOVIE_VIDEO_SCREEN_CAPTURE(MediaMetadata.PICTURE_TYPE_MOVIE_VIDEO_SCREEN_CAPTURE),
+
+ /**
+ * A bright coloured fish.
+ * [what?](https://musicfans.stackexchange.com/questions/14446/reason-for-id3-bright-colored-fish)
+ */
+ A_BRIGHT_COLORED_FISH(MediaMetadata.PICTURE_TYPE_A_BRIGHT_COLORED_FISH),
+
+ /**
+ * Illustration.
+ */
+ ILLUSTRATION(MediaMetadata.PICTURE_TYPE_ILLUSTRATION),
+
+ /**
+ * Band/artist logotype.
+ */
+ BAND_ARTIST_LOGO(MediaMetadata.PICTURE_TYPE_BAND_ARTIST_LOGO),
+
+ /**
+ * Publisher/Studio logotype.
+ */
+ PUBLISHER_STUDIO_LOGO(MediaMetadata.PICTURE_TYPE_PUBLISHER_STUDIO_LOGO);
+
+ companion object {
+ fun fromMedia3Value(value: @MediaMetadata.PictureType Int) = entries.firstOrNull {
+ it.media3Value == value
+ } ?: throw Exception("Unknown picture type $value")
+ }
+ }
+
init {
require(uri != null || bitmap != null) {
"At least one of the fields should be non-null"
@@ -28,6 +148,7 @@
override fun compareTo(other: Thumbnail) = compareValuesBy(
this, other,
Thumbnail::uri,
+ Thumbnail::type,
).let {
if (it == 0) {
return@let when (this.bitmap?.sameAs(other.bitmap)) {