Выберите аудио файл в exoplayer - PullRequest
0 голосов
/ 05 сентября 2018

Я создаю аудиопроигрыватель для 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 и перезапустив намерение (остановив его и создав новый), когда часть исходного списка песен я хочу каждый раз, когда нажимается какой-либо элемент. Есть ли лучший способ добиться того же? Также, что будет лучшим способом сделать нижний лист для контроля и приостановки воспроизведения? Большое спасибо заранее.

...