Как воспроизвести несколько аудио URI последовательно, используя exoplayer? - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь воспроизвести звук с помощью exoplayer.

У меня есть несколько файлов в локальном каталоге, и я хочу воспроизвести их последовательно. Я пытаюсь добавить несколько идентификаторов URI в MediaSource, но не могу найти решение.

Здесь первый файл воспроизводится правильно, но ни один из остальных. Я использую ExoPlayer версии 2.9.2

Примечание. В моем случае файлы в папке «Статьи» будут динамически обновляться во время работы проигрывателя.

Пожалуйста, предложите решение. Мой код:

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 dataSourceFactory: DataSource.Factory? = null
private var extractorsFactory: ExtractorsFactory? = null
private var dynamicConcatenatingMediaSource: ConcatenatingMediaSource? = null

override fun onCreate() {
    super.onCreate()
    val context: Context = this
    player = ExoPlayerFactory.newSimpleInstance(this)
    dataSourceFactory = DefaultDataSourceFactory(context, BuildConfig.APPLICATION_ID)
    extractorsFactory = DefaultExtractorsFactory()

    var file: File = File(Environment.getExternalStorageDirectory().absolutePath + "/Articles")

    /*for (i in file.listFiles()){
        Log.e("","" +file.listFiles())
    }*/

    var uri =
        Uri.parse(Environment.getExternalStorageDirectory().absolutePath + "/Articles" + "/article_tts" + 0 + ".wav")


    //if (dynamicConcatenatingMediaSource == null)
    dynamicConcatenatingMediaSource = ConcatenatingMediaSource()
    val mediaSource: MediaSource =
        ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
    dynamicConcatenatingMediaSource?.addMediaSource(mediaSource)

    player?.prepare(dynamicConcatenatingMediaSource)
    player?.setPlayWhenReady(true)

    player?.addListener(object : Player.EventListener {
        override fun onTracksChanged(
            trackGroups: TrackGroupArray?,
            trackSelections: TrackSelectionArray?
        ) {

        }

        override fun onPlayerError(error: ExoPlaybackException?) {
            stopSelf()
        }

        override fun onLoadingChanged(isLoading: Boolean) {

        }

        override fun onPositionDiscontinuity(reason: Int) {

        }

        override fun onRepeatModeChanged(repeatMode: Int) {

        }

        override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {

        }

        override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {

        }

        override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
            if (playbackState == Player.STATE_ENDED) {
                player?.stop()
                stopSelf()
            }
        }

        override fun onSeekProcessed() {

        }

        override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {

        }
    })

    playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
        context,
        "playback_channel",
        R.string.playback_channel_name,
        7001,
        object : MediaDescriptionAdapter {
            override fun getCurrentContentTitle(player: Player): String {
                return "Playlist"
            }

            override fun createCurrentContentIntent(player: Player): PendingIntent? {
                return null
            }

            override fun getCurrentContentText(player: Player): String? {
                return "Playlist Demo"
            }

            override fun getCurrentLargeIcon(
                player: Player,
                callback: BitmapCallback
            ): Bitmap? {
                return getBitmap(context, R.drawable.ic_vikatan_logo_new)
            }
        }
    )
    playerNotificationManager?.setNotificationListener(object :
        PlayerNotificationManager.NotificationListener {
        override fun onNotificationStarted(
            notificationId: Int,
            notification: Notification
        ) {
            startForeground(notificationId, notification)
        }

        override fun onNotificationCancelled(notificationId: Int) {
            stopSelf()
        }
    })

    playerNotificationManager?.setPriority(NotificationCompat.PRIORITY_HIGH);
    playerNotificationManager?.setUseNavigationActions(false)
    playerNotificationManager?.setFastForwardIncrementMs(0)
    playerNotificationManager?.setRewindIncrementMs(0)
    playerNotificationManager?.setUsePlayPauseActions(true);
    playerNotificationManager?.setPlayer(player)

    mediaSession = MediaSessionCompat(context, "audio")
    mediaSession?.setActive(true)
    playerNotificationManager?.setMediaSessionToken(mediaSession?.getSessionToken())

    mediaSessionConnector = MediaSessionConnector(mediaSession)
    mediaSessionConnector?.setQueueNavigator(object : TimelineQueueNavigator(mediaSession) {
        override fun getMediaDescription(
            player: Player,
            windowIndex: Int
        ): MediaDescriptionCompat {
            return getMediaDescription(context)
        }
    })
    mediaSessionConnector?.setPlayer(player, null)
}

override fun onDestroy() {
    mediaSession!!.release()
    mediaSessionConnector!!.setPlayer(null, null)
    playerNotificationManager!!.setPlayer(null)
    player!!.release()
    player = null
    super.onDestroy()
}

override fun onBind(intent: Intent?): IBinder? {
    return null
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    return START_STICKY
}

fun getBitmap(context: Context, @DrawableRes bitmapResource: Int): Bitmap {
    return (context.resources.getDrawable(bitmapResource) as BitmapDrawable).bitmap
}

fun getMediaDescription(context: Context?): MediaDescriptionCompat {
    val extras = Bundle()
    val bitmap: Bitmap = getBitmap(context!!, R.drawable.ic_vikatan_logo_new)
    extras.putParcelable(
        MediaMetadataCompat.METADATA_KEY_ALBUM_ART,
        bitmap
    )
    extras.putParcelable(
        MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON,
        bitmap
    )
    return MediaDescriptionCompat.Builder()
        .setMediaId("audio_id")
        .setIconBitmap(bitmap)
        .setTitle("Playlist")
        .setDescription("Playlist Demo")
        .setExtras(extras)
        .build()
}
}

1 Ответ

0 голосов
/ 04 марта 2020

Используйте объединенный источник мультимедиа.

private val concatenatingMediaSource  = ConcatenatingMediaSource()

Затем создайте отдельный медиа-источник для каждого аудиофайла и добавьте к concatenatingMediaSource с помощью

concatenatingMediaSource.addMediaSource(your_media_source_object)
...