media3 ExoPlayer в RecyclerView

Всем привет, подскажите, пожалуйста, как правильно реализовать управление медиа файлами. У меня есть приложение - чат, в котором отображаются голосовые сообщения и MediaSessionService реализованный согласно документации. На данный момент при воспроизведении одного голосового, включаются все голосовые, которые находятся в зоне видимости экрана и воспроизводится один медиафайл. Подскажите, пожалуйста, как правильно настроить viewHolder что бы для каждого голосового был свой медиафайл? Мой Service:

class PlayerService : MediaSessionService(),MediaSession.Callback {
companion object {
    private val _isPlay = MutableStateFlow<Boolean>(false)
    val isPlay: StateFlow<Boolean> = _isPlay

    var currentVoiceName: String? = null
}

private var mediaSession: MediaSession? = null

override fun onCreate() {
    super.onCreate()
    val exoPlayer =
        ExoPlayer.Builder(applicationContext, DefaultRenderersFactory(applicationContext))
            .setLoadControl(
                DefaultLoadControl.Builder()
                    .setPrioritizeTimeOverSizeThresholds(false).build()
            )
            .setTrackSelector(
                DefaultTrackSelector(
                    applicationContext,
                    AdaptiveTrackSelection.Factory()
                )
            )
            .setMediaSourceFactory(
                ProgressiveMediaSource.Factory(
                    CacheDataSource.Factory()
                        .setCache(AppCommunity.cache)
                        .setUpstreamDataSourceFactory(
                            DefaultHttpDataSource.Factory()
                                .setUserAgent("Exoplayer")
                        )
                        .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
                )
            )
            .build()
    mediaSession = MediaSession.Builder(this, exoPlayer).setCallback(this).build()
    exoPlayer.addListener(object : Player.Listener {
        override fun onPlaybackStateChanged(playbackState: Int) {
            _isPlay.value = !(playbackState == Player.STATE_ENDED && !exoPlayer.isPlaying)
            Timber.d("IsPlay = ${_isPlay.value}")
            if (!_isPlay.value) {
                currentVoiceName = null
                mediaSession?.player?.clearMediaItems()
            }
            super.onPlaybackStateChanged(playbackState)
        }

        override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
            currentVoiceName = mediaItem?.mediaMetadata?.artist?.toString()
            super.onMediaItemTransition(mediaItem, reason)
        }
    })
}

override fun onTaskRemoved(rootIntent: Intent?) {
    val player = mediaSession?.player!!
    if (!player.playWhenReady
        || player.mediaItemCount == 0
        || player.playbackState == Player.STATE_ENDED
    ) stopSelf()

}

override fun onDestroy() {
    super.onDestroy()
    mediaSession?.run {
        player.release()
        release()
        mediaSession = null
    }
}

override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
    return mediaSession
}

override fun onConnect(
    session: MediaSession,
    controller: MediaSession.ControllerInfo
): MediaSession.ConnectionResult {
    Timber.d(controller.toString())
    return super.onConnect(session, controller)
}

}

мой viewHolder

  private var controllerFuture: ListenableFuture<MediaController>? = null
override fun onBinding(item: MessageItem) {
    super.onBinding(item)
    if (item !is MessageItem.ContentMessage)
        return

    binding.time.text = item.createDateAt
    if (item.editDateAt != null) {
        binding.time.text = itemView.context.getString(R.string.change_in, item.editDateAt)
    }

    if (item.itemMessageState == MessageState.DISPLAYED)
        binding.checkMarkers.setImageResource(R.drawable.ic_check_marks_done)
    else binding.checkMarkers.setImageResource(R.drawable.ic_check_send)
    val mediaItem = MediaItem.Builder()
        .setUri(item.listContent[0].uri)
        .setMediaId(item.itemMessageId)
        .setMediaMetadata(
            MediaMetadata.Builder()
                .setArtist(item.userName)
                .setTitle(itemView.context.getString(R.string.voice))
                .build()
        )

    val sessionToken = SessionToken(itemView.context, ComponentName(itemView.context, PlayerService::class.java))
    controllerFuture = MediaController.Builder(itemView.context, sessionToken).buildAsync()
    controllerFuture!!.addListener(
        {
            with(controllerFuture!!.get()) {
                addMediaItem(mediaItem.build())
                binding.exoplayerView.player = this
                playWhenReady = false
                prepare()
        },
        MoreExecutors.directExecutor()
    )

}

private fun releasePlayer() {
    binding.exoplayerView.player?.release()
    binding.exoplayerView.player = null
    controllerFuture?.let { MediaController.releaseFuture(it) }
}

override fun onDestroyView() {
    super.onDestroyView()
    Timber.d("onDestroyView")
    releasePlayer()
}

Ответы (0 шт):