mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-18 18:17:43 +03:00
Merge branch 'modernize' into 'develop'
Modernize code after media3 1.1.0 update See merge request ultrasonic/ultrasonic!1077
This commit is contained in:
commit
6eb7c9d25c
@ -11,7 +11,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.media3.session.BitmapLoader
|
import androidx.media3.common.util.BitmapLoader
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService
|
import com.google.common.util.concurrent.ListeningExecutorService
|
||||||
import com.google.common.util.concurrent.MoreExecutors
|
import com.google.common.util.concurrent.MoreExecutors
|
||||||
|
@ -7,16 +7,15 @@
|
|||||||
|
|
||||||
package org.moire.ultrasonic.playback
|
package org.moire.ultrasonic.playback
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.media3.common.HeartRating
|
import androidx.media3.common.HeartRating
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.MediaMetadata
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_FOLDER_ALBUMS
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_ALBUMS
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_FOLDER_ARTISTS
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_ARTISTS
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_FOLDER_MIXED
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_MIXED
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_FOLDER_PLAYLISTS
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_PLAYLISTS
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_MIXED
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_TITLES
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_PLAYLIST
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.Rating
|
import androidx.media3.common.Rating
|
||||||
import androidx.media3.common.StarRating
|
import androidx.media3.common.StarRating
|
||||||
@ -46,7 +45,6 @@ import org.moire.ultrasonic.domain.MusicDirectory
|
|||||||
import org.moire.ultrasonic.domain.SearchCriteria
|
import org.moire.ultrasonic.domain.SearchCriteria
|
||||||
import org.moire.ultrasonic.domain.SearchResult
|
import org.moire.ultrasonic.domain.SearchResult
|
||||||
import org.moire.ultrasonic.domain.Track
|
import org.moire.ultrasonic.domain.Track
|
||||||
import org.moire.ultrasonic.service.MediaPlayerManager
|
|
||||||
import org.moire.ultrasonic.service.MusicServiceFactory
|
import org.moire.ultrasonic.service.MusicServiceFactory
|
||||||
import org.moire.ultrasonic.service.RatingManager
|
import org.moire.ultrasonic.service.RatingManager
|
||||||
import org.moire.ultrasonic.util.Util
|
import org.moire.ultrasonic.util.Util
|
||||||
@ -97,11 +95,8 @@ const val PLAY_COMMAND = "play "
|
|||||||
* MediaBrowserService implementation for e.g. Android Auto
|
* MediaBrowserService implementation for e.g. Android Auto
|
||||||
*/
|
*/
|
||||||
@Suppress("TooManyFunctions", "LargeClass", "UnusedPrivateMember")
|
@Suppress("TooManyFunctions", "LargeClass", "UnusedPrivateMember")
|
||||||
@SuppressLint("UnsafeOptInUsageError")
|
class AutoMediaBrowserCallback : MediaLibraryService.MediaLibrarySession.Callback, KoinComponent {
|
||||||
class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|
||||||
MediaLibraryService.MediaLibrarySession.Callback, KoinComponent {
|
|
||||||
|
|
||||||
private val mediaPlayerManager by inject<MediaPlayerManager>()
|
|
||||||
private val activeServerProvider: ActiveServerProvider by inject()
|
private val activeServerProvider: ActiveServerProvider by inject()
|
||||||
|
|
||||||
private val serviceJob = SupervisorJob()
|
private val serviceJob = SupervisorJob()
|
||||||
@ -213,8 +208,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
"Root Folder",
|
"Root Folder",
|
||||||
MEDIA_ROOT_ID,
|
MEDIA_ROOT_ID,
|
||||||
isPlayable = false,
|
isPlayable = false,
|
||||||
folderType = FOLDER_TYPE_MIXED,
|
isBrowsable = true,
|
||||||
mediaType = MediaMetadata.MEDIA_TYPE_FOLDER_MIXED
|
mediaType = MEDIA_TYPE_FOLDER_MIXED
|
||||||
),
|
),
|
||||||
params
|
params
|
||||||
)
|
)
|
||||||
@ -528,7 +523,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
?: Futures.immediateFuture(mediaItems)
|
?: Futures.immediateFuture(mediaItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ComplexMethod")
|
@Suppress("ReturnCount", "ComplexMethod")
|
||||||
private fun onLoadChildren(
|
private fun onLoadChildren(
|
||||||
parentId: String,
|
parentId: String,
|
||||||
): ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> {
|
): ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> {
|
||||||
@ -598,8 +593,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
album.title ?: "",
|
album.title ?: "",
|
||||||
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
||||||
.joinToString("|"),
|
.joinToString("|")
|
||||||
FOLDER_TYPE_ALBUMS
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,7 +685,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.music_library_label,
|
R.string.music_library_label,
|
||||||
MEDIA_LIBRARY_ID,
|
MEDIA_LIBRARY_ID,
|
||||||
null,
|
null,
|
||||||
folderType = FOLDER_TYPE_MIXED,
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_FOLDER_MIXED,
|
||||||
icon = R.drawable.ic_library
|
icon = R.drawable.ic_library
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -699,7 +694,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.main_artists_title,
|
R.string.main_artists_title,
|
||||||
MEDIA_ARTIST_ID,
|
MEDIA_ARTIST_ID,
|
||||||
null,
|
null,
|
||||||
folderType = FOLDER_TYPE_ARTISTS,
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_FOLDER_ARTISTS,
|
||||||
icon = R.drawable.ic_artist
|
icon = R.drawable.ic_artist
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -708,7 +704,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.main_albums_title,
|
R.string.main_albums_title,
|
||||||
MEDIA_ALBUM_ID,
|
MEDIA_ALBUM_ID,
|
||||||
null,
|
null,
|
||||||
folderType = FOLDER_TYPE_ALBUMS,
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_FOLDER_ALBUMS,
|
||||||
icon = R.drawable.ic_menu_browse
|
icon = R.drawable.ic_menu_browse
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -716,7 +713,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.playlist_label,
|
R.string.playlist_label,
|
||||||
MEDIA_PLAYLIST_ID,
|
MEDIA_PLAYLIST_ID,
|
||||||
null,
|
null,
|
||||||
folderType = FOLDER_TYPE_PLAYLISTS,
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_FOLDER_PLAYLISTS,
|
||||||
icon = R.drawable.ic_menu_playlists
|
icon = R.drawable.ic_menu_playlists
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -731,14 +729,16 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.main_songs_random,
|
R.string.main_songs_random,
|
||||||
MEDIA_SONG_RANDOM_ID,
|
MEDIA_SONG_RANDOM_ID,
|
||||||
R.string.main_songs_title,
|
R.string.main_songs_title,
|
||||||
folderType = FOLDER_TYPE_TITLES
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_PLAYLIST
|
||||||
)
|
)
|
||||||
|
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
R.string.main_songs_starred,
|
R.string.main_songs_starred,
|
||||||
MEDIA_SONG_STARRED_ID,
|
MEDIA_SONG_STARRED_ID,
|
||||||
R.string.main_songs_title,
|
R.string.main_songs_title,
|
||||||
folderType = FOLDER_TYPE_TITLES
|
isBrowsable = true,
|
||||||
|
mediaType = MEDIA_TYPE_PLAYLIST
|
||||||
)
|
)
|
||||||
|
|
||||||
// Albums
|
// Albums
|
||||||
@ -752,28 +752,28 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
R.string.main_albums_recent,
|
R.string.main_albums_recent,
|
||||||
MEDIA_ALBUM_RECENT_ID,
|
MEDIA_ALBUM_RECENT_ID,
|
||||||
R.string.main_albums_title,
|
R.string.main_albums_title,
|
||||||
folderType = FOLDER_TYPE_ALBUMS
|
mediaType = MEDIA_TYPE_FOLDER_ALBUMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
R.string.main_albums_frequent,
|
R.string.main_albums_frequent,
|
||||||
MEDIA_ALBUM_FREQUENT_ID,
|
MEDIA_ALBUM_FREQUENT_ID,
|
||||||
R.string.main_albums_title,
|
R.string.main_albums_title,
|
||||||
folderType = FOLDER_TYPE_ALBUMS
|
mediaType = MEDIA_TYPE_FOLDER_ALBUMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
R.string.main_albums_random,
|
R.string.main_albums_random,
|
||||||
MEDIA_ALBUM_RANDOM_ID,
|
MEDIA_ALBUM_RANDOM_ID,
|
||||||
R.string.main_albums_title,
|
R.string.main_albums_title,
|
||||||
folderType = FOLDER_TYPE_ALBUMS
|
mediaType = MEDIA_TYPE_FOLDER_ALBUMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
R.string.main_albums_starred,
|
R.string.main_albums_starred,
|
||||||
MEDIA_ALBUM_STARRED_ID,
|
MEDIA_ALBUM_STARRED_ID,
|
||||||
R.string.main_albums_title,
|
R.string.main_albums_title,
|
||||||
folderType = FOLDER_TYPE_ALBUMS
|
mediaType = MEDIA_TYPE_FOLDER_ALBUMS,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
@ -822,8 +822,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
index.add(currentSection)
|
index.add(currentSection)
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
currentSection,
|
currentSection,
|
||||||
listOf(MEDIA_ARTIST_SECTION, currentSection).joinToString("|"),
|
listOf(MEDIA_ARTIST_SECTION, currentSection).joinToString("|")
|
||||||
FOLDER_TYPE_ARTISTS
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -831,8 +830,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
artists.map { artist ->
|
artists.map { artist ->
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
artist.name ?: "",
|
artist.name ?: "",
|
||||||
listOf(childMediaId, artist.id, artist.name).joinToString("|"),
|
listOf(childMediaId, artist.id, artist.name).joinToString("|")
|
||||||
FOLDER_TYPE_ARTISTS
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,8 +860,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
album.title ?: "",
|
album.title ?: "",
|
||||||
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
||||||
.joinToString("|"),
|
.joinToString("|")
|
||||||
FOLDER_TYPE_ALBUMS
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@future LibraryResult.ofItemList(mediaItems, null)
|
return@future LibraryResult.ofItemList(mediaItems, null)
|
||||||
@ -901,8 +898,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
if (item.isDirectory)
|
if (item.isDirectory)
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
item.title ?: "",
|
item.title ?: "",
|
||||||
listOf(MEDIA_ALBUM_ITEM, item.id, item.name).joinToString("|"),
|
listOf(MEDIA_ALBUM_ITEM, item.id, item.name).joinToString("|")
|
||||||
FOLDER_TYPE_TITLES
|
|
||||||
)
|
)
|
||||||
else if (item is Track)
|
else if (item is Track)
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
@ -951,8 +947,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
album.title ?: "",
|
album.title ?: "",
|
||||||
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
listOf(MEDIA_ALBUM_ITEM, album.id, album.name)
|
||||||
.joinToString("|"),
|
.joinToString("|")
|
||||||
FOLDER_TYPE_ALBUMS
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -980,7 +975,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
playlist.name,
|
playlist.name,
|
||||||
listOf(MEDIA_PLAYLIST_ITEM, playlist.id, playlist.name)
|
listOf(MEDIA_PLAYLIST_ITEM, playlist.id, playlist.name)
|
||||||
.joinToString("|"),
|
.joinToString("|"),
|
||||||
FOLDER_TYPE_PLAYLISTS
|
mediaType = MEDIA_TYPE_PLAYLIST,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@future LibraryResult.ofItemList(mediaItems, null)
|
return@future LibraryResult.ofItemList(mediaItems, null)
|
||||||
@ -1074,7 +1069,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
podcast.title ?: "",
|
podcast.title ?: "",
|
||||||
listOf(MEDIA_PODCAST_ITEM, podcast.id).joinToString("|"),
|
listOf(MEDIA_PODCAST_ITEM, podcast.id).joinToString("|"),
|
||||||
FOLDER_TYPE_MIXED
|
mediaType = MEDIA_TYPE_FOLDER_MIXED,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@future LibraryResult.ofItemList(mediaItems, null)
|
return@future LibraryResult.ofItemList(mediaItems, null)
|
||||||
@ -1177,7 +1172,7 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
share.name ?: "",
|
share.name ?: "",
|
||||||
listOf(MEDIA_SHARE_ITEM, share.id)
|
listOf(MEDIA_SHARE_ITEM, share.id)
|
||||||
.joinToString("|"),
|
.joinToString("|"),
|
||||||
FOLDER_TYPE_MIXED
|
mediaType = MEDIA_TYPE_FOLDER_MIXED,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@future LibraryResult.ofItemList(mediaItems, null)
|
return@future LibraryResult.ofItemList(mediaItems, null)
|
||||||
@ -1355,14 +1350,16 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
private fun MutableList<MediaItem>.add(
|
private fun MutableList<MediaItem>.add(
|
||||||
title: String,
|
title: String,
|
||||||
mediaId: String,
|
mediaId: String,
|
||||||
folderType: Int
|
mediaType: Int = MEDIA_TYPE_MIXED,
|
||||||
|
isBrowsable: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val mediaItem = buildMediaItem(
|
val mediaItem = buildMediaItem(
|
||||||
title,
|
title,
|
||||||
mediaId,
|
mediaId,
|
||||||
isPlayable = false,
|
isPlayable = false,
|
||||||
folderType = folderType
|
isBrowsable = isBrowsable,
|
||||||
|
mediaType = mediaType
|
||||||
)
|
)
|
||||||
|
|
||||||
this.add(mediaItem)
|
this.add(mediaItem)
|
||||||
@ -1373,8 +1370,8 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
resId: Int,
|
resId: Int,
|
||||||
mediaId: String,
|
mediaId: String,
|
||||||
groupNameId: Int?,
|
groupNameId: Int?,
|
||||||
browsable: Boolean = true,
|
isBrowsable: Boolean = true,
|
||||||
folderType: Int = FOLDER_TYPE_MIXED,
|
mediaType: Int = MEDIA_TYPE_FOLDER_MIXED,
|
||||||
icon: Int? = null
|
icon: Int? = null
|
||||||
) {
|
) {
|
||||||
val applicationContext = UApp.applicationContext()
|
val applicationContext = UApp.applicationContext()
|
||||||
@ -1382,14 +1379,15 @@ class AutoMediaBrowserCallback(val libraryService: MediaLibraryService) :
|
|||||||
val mediaItem = buildMediaItem(
|
val mediaItem = buildMediaItem(
|
||||||
applicationContext.getString(resId),
|
applicationContext.getString(resId),
|
||||||
mediaId,
|
mediaId,
|
||||||
isPlayable = !browsable,
|
isPlayable = !isBrowsable,
|
||||||
folderType = folderType,
|
isBrowsable = isBrowsable,
|
||||||
|
imageUri = if (icon != null) {
|
||||||
|
Util.getUriToDrawable(applicationContext, icon)
|
||||||
|
} else null,
|
||||||
group = if (groupNameId != null) {
|
group = if (groupNameId != null) {
|
||||||
applicationContext.getString(groupNameId)
|
applicationContext.getString(groupNameId)
|
||||||
} else null,
|
} else null,
|
||||||
imageUri = if (icon != null) {
|
mediaType = mediaType
|
||||||
Util.getUriToDrawable(applicationContext, icon)
|
|
||||||
} else null
|
|
||||||
)
|
)
|
||||||
|
|
||||||
this.add(mediaItem)
|
this.add(mediaItem)
|
||||||
|
@ -142,7 +142,7 @@ class PlaybackService :
|
|||||||
actualBackend = desiredBackend
|
actualBackend = desiredBackend
|
||||||
|
|
||||||
// Create browser interface
|
// Create browser interface
|
||||||
librarySessionCallback = AutoMediaBrowserCallback(this)
|
librarySessionCallback = AutoMediaBrowserCallback()
|
||||||
|
|
||||||
// This will need to use the AutoCalls
|
// This will need to use the AutoCalls
|
||||||
mediaLibrarySession = MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
mediaLibrarySession = MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
||||||
|
@ -82,7 +82,10 @@ class JukeboxMediaPlayer : JukeboxUnimplementedFunctions(), Player {
|
|||||||
companion object {
|
companion object {
|
||||||
// This is quite important, by setting the DeviceInfo the player is recognized by
|
// This is quite important, by setting the DeviceInfo the player is recognized by
|
||||||
// Android as being a remote playback surface
|
// Android as being a remote playback surface
|
||||||
val DEVICE_INFO = DeviceInfo(DeviceInfo.PLAYBACK_TYPE_REMOTE, 0, 10)
|
val DEVICE_INFO = DeviceInfo.Builder(DeviceInfo.PLAYBACK_TYPE_REMOTE)
|
||||||
|
.setMinVolume(0)
|
||||||
|
.setMaxVolume(10)
|
||||||
|
.build()
|
||||||
val running = AtomicBoolean()
|
val running = AtomicBoolean()
|
||||||
const val MAX_GAIN = 10
|
const val MAX_GAIN = 10
|
||||||
}
|
}
|
||||||
@ -208,15 +211,12 @@ class JukeboxMediaPlayer : JukeboxUnimplementedFunctions(), Player {
|
|||||||
Player.COMMAND_GET_DEVICE_VOLUME,
|
Player.COMMAND_GET_DEVICE_VOLUME,
|
||||||
Player.COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
|
Player.COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
|
||||||
Player.COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS,
|
Player.COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS,
|
||||||
Player.COMMAND_ADJUST_DEVICE_VOLUME,
|
|
||||||
Player.COMMAND_SET_DEVICE_VOLUME
|
|
||||||
)
|
)
|
||||||
if (isPlaying) commandsBuilder.add(Player.COMMAND_STOP)
|
if (isPlaying) commandsBuilder.add(Player.COMMAND_STOP)
|
||||||
if (playlist.isNotEmpty()) {
|
if (playlist.isNotEmpty()) {
|
||||||
commandsBuilder.addAll(
|
commandsBuilder.addAll(
|
||||||
Player.COMMAND_GET_CURRENT_MEDIA_ITEM,
|
Player.COMMAND_GET_CURRENT_MEDIA_ITEM,
|
||||||
Player.COMMAND_GET_METADATA,
|
Player.COMMAND_GET_METADATA,
|
||||||
Player.COMMAND_GET_MEDIA_ITEMS_METADATA,
|
|
||||||
Player.COMMAND_PLAY_PAUSE,
|
Player.COMMAND_PLAY_PAUSE,
|
||||||
Player.COMMAND_PREPARE,
|
Player.COMMAND_PREPARE,
|
||||||
Player.COMMAND_SEEK_BACK,
|
Player.COMMAND_SEEK_BACK,
|
||||||
|
@ -14,7 +14,8 @@ import androidx.core.net.toUri
|
|||||||
import androidx.media3.common.HeartRating
|
import androidx.media3.common.HeartRating
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.MediaMetadata
|
import androidx.media3.common.MediaMetadata
|
||||||
import androidx.media3.common.MediaMetadata.FOLDER_TYPE_NONE
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_FOLDER_MIXED
|
||||||
|
import androidx.media3.common.MediaMetadata.MEDIA_TYPE_MUSIC
|
||||||
import androidx.media3.common.StarRating
|
import androidx.media3.common.StarRating
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
@ -22,7 +23,7 @@ import java.util.Date
|
|||||||
import org.moire.ultrasonic.domain.Track
|
import org.moire.ultrasonic.domain.Track
|
||||||
import org.moire.ultrasonic.provider.AlbumArtContentProvider
|
import org.moire.ultrasonic.provider.AlbumArtContentProvider
|
||||||
|
|
||||||
// Copied from androidx.media.utils.MediaConstants in order to avoid importing a whole dependecy
|
// Copied from androidx.media.utils.MediaConstants in order to avoid importing a whole dependency
|
||||||
// for a single string value
|
// for a single string value
|
||||||
private const val DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE =
|
private const val DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE =
|
||||||
"android.media.browse.CONTENT_STYLE_GROUP_TITLE_HINT"
|
"android.media.browse.CONTENT_STYLE_GROUP_TITLE_HINT"
|
||||||
@ -76,15 +77,16 @@ fun Track.toMediaItem(
|
|||||||
title = title ?: "",
|
title = title ?: "",
|
||||||
mediaId = mediaId,
|
mediaId = mediaId,
|
||||||
isPlayable = !isDirectory,
|
isPlayable = !isDirectory,
|
||||||
folderType = if (isDirectory) MediaMetadata.FOLDER_TYPE_TITLES
|
isBrowsable = isDirectory,
|
||||||
else MediaMetadata.FOLDER_TYPE_NONE,
|
|
||||||
album = album,
|
album = album,
|
||||||
artist = artist,
|
artist = artist,
|
||||||
genre = genre,
|
genre = genre,
|
||||||
sourceUri = uri.toUri(),
|
sourceUri = uri.toUri(),
|
||||||
imageUri = artworkUri,
|
imageUri = artworkUri,
|
||||||
starred = starred,
|
starred = starred,
|
||||||
group = null
|
group = null,
|
||||||
|
mediaType = if (isDirectory) MEDIA_TYPE_FOLDER_MIXED
|
||||||
|
else MEDIA_TYPE_MUSIC
|
||||||
)
|
)
|
||||||
|
|
||||||
val metadataBuilder = mediaItem.mediaMetadata.buildUpon()
|
val metadataBuilder = mediaItem.mediaMetadata.buildUpon()
|
||||||
@ -204,14 +206,6 @@ private fun safeParseDate(created: String?): Date? {
|
|||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MediaItem.setPin(pin: Boolean) {
|
|
||||||
this.mediaMetadata.extras?.putBoolean("pin", pin)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun MediaItem.shouldBePinned(): Boolean {
|
|
||||||
return this.mediaMetadata.extras?.getBoolean("pin") ?: false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a new MediaItem from a list of attributes.
|
* Build a new MediaItem from a list of attributes.
|
||||||
* Especially useful to create folder entries in the Auto interface.
|
* Especially useful to create folder entries in the Auto interface.
|
||||||
@ -222,7 +216,7 @@ fun buildMediaItem(
|
|||||||
title: String,
|
title: String,
|
||||||
mediaId: String,
|
mediaId: String,
|
||||||
isPlayable: Boolean,
|
isPlayable: Boolean,
|
||||||
folderType: @MediaMetadata.FolderType Int,
|
isBrowsable: Boolean = false,
|
||||||
album: String? = null,
|
album: String? = null,
|
||||||
artist: String? = null,
|
artist: String? = null,
|
||||||
genre: String? = null,
|
genre: String? = null,
|
||||||
@ -241,17 +235,13 @@ fun buildMediaItem(
|
|||||||
.setAlbumArtist(artist)
|
.setAlbumArtist(artist)
|
||||||
.setGenre(genre)
|
.setGenre(genre)
|
||||||
.setUserRating(HeartRating(starred))
|
.setUserRating(HeartRating(starred))
|
||||||
.setFolderType(folderType)
|
.setIsBrowsable(isBrowsable)
|
||||||
.setIsPlayable(isPlayable)
|
.setIsPlayable(isPlayable)
|
||||||
|
|
||||||
if (imageUri != null) {
|
if (imageUri != null) {
|
||||||
metadataBuilder.setArtworkUri(imageUri)
|
metadataBuilder.setArtworkUri(imageUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folderType > FOLDER_TYPE_NONE) {
|
|
||||||
metadataBuilder.setIsBrowsable(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mediaType != null) {
|
if (mediaType != null) {
|
||||||
metadataBuilder.setMediaType(mediaType)
|
metadataBuilder.setMediaType(mediaType)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user