Я создаю аудиопроигрыватель для Android и получаю список песен (URL, имя и т. Д.) Из облачного пожарного магазина. Теперь я хочу отобразить все песни в виде элементов в Recycler View и выбрать, какую песню воспроизводить. Есть ли способ выбрать, какую песню воспроизводить из списка песен, с которыми был запущен exoplayer (используя concatenatingMediaSource)?
Вот класс AudioService: -
class AudioPlayerService: Service() {
private var player: SimpleExoPlayer? = null
private var playerNotificationManager: PlayerNotificationManager? = null
private var mediaSession: MediaSessionCompat? = null
private var mediaSessionConnector: MediaSessionConnector? = null
private var songList: ArrayList<MetaData>? = null
private var context: Context? = null
override fun onCreate() {
super.onCreate()
context = this
val descriptionAdapter = object : PlayerNotificationManager.MediaDescriptionAdapter {
override fun getCurrentContentTitle(player: Player?): String {
return songList!![player!!.currentWindowIndex].name
}
override fun getCurrentContentText(player: Player?): String? {
return songList!![player!!.currentWindowIndex].artist
}
override fun getCurrentLargeIcon(player: Player?, callback: PlayerNotificationManager.BitmapCallback?): Bitmap? {
return null
}
override fun createCurrentContentIntent(player: Player?): PendingIntent? {
val intent = Intent(context, MainActivity::class.java)
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
this, "1", R.string.app_name, 1, descriptionAdapter
)
val notificationListener = object : PlayerNotificationManager.NotificationListener {
override fun onNotificationStarted(notificationId: Int, notification: Notification?) {
startForeground(notificationId, notification)
}
override fun onNotificationCancelled(notificationId: Int) {
stopSelf()
}
}
playerNotificationManager!!.setNotificationListener(
notificationListener
)
mediaSession = MediaSessionCompat(context, "Test")
mediaSession!!.isActive = true
playerNotificationManager!!.setMediaSessionToken(mediaSession!!.sessionToken)
mediaSessionConnector = MediaSessionConnector(mediaSession)
val timelineQueueNavigator = object: TimelineQueueNavigator(mediaSession) {
override fun getMediaDescription(player: Player?, windowIndex: Int): MediaDescriptionCompat {
return getMediaDescription(songList!![windowIndex])
}
}
mediaSessionConnector!!.setQueueNavigator(timelineQueueNavigator)
}
override fun onDestroy() {
super.onDestroy()
mediaSession!!.release()
mediaSessionConnector!!.setPlayer(null, null)
playerNotificationManager!!.setPlayer(null)
player!!.release()
player = null
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
songList = intent!!.getParcelableArrayListExtra<MetaData>("list")
context = this
player = ExoPlayerFactory.newSimpleInstance(this, DefaultTrackSelector())
val dataSource = DefaultDataSourceFactory(
this, Util.getUserAgent(this, "Playlist"))
val concatenatingMediaSource = ConcatenatingMediaSource()
for(item in songList!!){
val mediaSource = ExtractorMediaSource.Factory(dataSource)
.createMediaSource(Uri.parse(item.url))
concatenatingMediaSource.addMediaSource(mediaSource)
}
player!!.prepare(concatenatingMediaSource)
player!!.playWhenReady = true
playerNotificationManager!!.setPlayer(player)
mediaSessionConnector!!.setPlayer(player, null)
return START_STICKY
}
private fun getMediaDescription(item: MetaData): MediaDescriptionCompat {
return MediaDescriptionCompat.Builder()
.setMediaId(item.id.toString())
.setTitle(item.name)
.setDescription(item.artist)
.setMediaUri(Uri.parse(item.url))
.build()
}
}
Основная деятельность: -
class MainActivity : AppCompatActivity() {
private var audioIntent: Intent? = null
private var myDB: FirebaseFirestore? = null
private val songList = ArrayList<MetaData>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myDB = FirebaseFirestore.getInstance()
initAppData()
}
override fun onDestroy() {
super.onDestroy()
stopService(audioIntent)
audioIntent = null
myDB = null
}
private fun initAppData() {
val docRef = myDB!!.collection("app").document("app_info")
docRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val playlistName = task.result.data!!["playlist"].toString()
initPlaylist(playlistName)
} else {
}
}
}
private fun initPlaylist(playlist: String) {
myDB!!.collection(playlist)
.orderBy("id")
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
for (document in task.result) {
songList.add(document.toObject(MetaData::class.java))
}
audioIntent = Intent(this, AudioPlayerService::class.java)
audioIntent!!.putExtra("list", songList)
Util.startForegroundService(this, audioIntent)
} else {
}
}
}
}
Я думаю, что это можно сделать частично, добавив слушателя ко всем элементам в представлении Recycler и перезапустив намерение (остановив его и создав новый), когда часть исходного списка песен я хочу каждый раз, когда нажимается какой-либо элемент. Есть ли лучший способ добиться того же?
Также, что будет лучшим способом сделать нижний лист для контроля и приостановки воспроизведения?
Большое спасибо заранее.