Android 如何使用exoplayer按顺序播放多个音频uri?
我正在尝试使用exoplayer播放音频 我在本地目录中有多个文件,我想按顺序播放它们。我正在尝试将多个URI添加到MediaSource,但找不到解决方案 在这里,第一个文件正在正确播放,但其余文件都没有。我使用的是ExoPlayer版本2.9.2 注意:在我的情况下,“文章”文件夹中的文件将在播放器运行时动态更新 请提出解决办法。我的代码:Android 如何使用exoplayer按顺序播放多个音频uri?,android,kotlin,uri,exoplayer,playlist,Android,Kotlin,Uri,Exoplayer,Playlist,我正在尝试使用exoplayer播放音频 我在本地目录中有多个文件,我想按顺序播放它们。我正在尝试将多个URI添加到MediaSource,但找不到解决方案 在这里,第一个文件正在正确播放,但其余文件都没有。我使用的是ExoPlayer版本2.9.2 注意:在我的情况下,“文章”文件夹中的文件将在播放器运行时动态更新 请提出解决办法。我的代码: class AudioPlayerService : Service() { private var player: SimpleExoPlayer?
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()
}
}
使用连接媒体源
private val concatenatingMediaSource = ConcatenatingMediaSource()
然后为每个音频文件创建单独的mediasource,并使用
concatenatingMediaSource.addMediaSource(your_media_source_object)