I would like to know how to be able to play more than two songs back to back in ExoPlayer using MediaSources I have in an ArrayList.
I can use ConcatenatingMediaSource
to be able to play two songs back to back, but I have to load them into this fundtion as separate paramters. I do not want to do this for a whole list of songs. I have tried to find an answer to this and seem to have some fundemental misunderstanding as I can't seem to replicate the efforts of others in other StackOverflow questions or blogs etc. (Many blogs show the simple two media source playlist as in the ExoPlayer docs).
This code is for context:
private fun prepareExoPlayer(songs: ListSongs) {
val uris = parseUris(songs)
val mediaSource = buildMediaSource(uris)
applyAudioAttributes()
simpleExoPlayer!!.prepare(mediaSource, false, false)
}
This code is where the issue is:
private fun buildMediaSource(uris: ArrayList<Uri>): MediaSource {
val userAgent = Util.getUserAgent(this, "MusicPlayer")
val defaultMediaSource = DefaultDataSourceFactory(this, userAgent)
val progressiveMediaSource = ProgressiveMediaSource.Factory(defaultMediaSource)
val mediaSources = ArrayList<MediaSource>()
for (uri in uris) {
mediaSources.add(progressiveMediaSource.createMediaSource(uri))
}
return if (mediaSources.size == 1) {
mediaSources[0]
} else {
val concatenatingMediaSource = ConcatenatingMediaSource()
concatenatingMediaSource.addMediaSources(mediaSources)
// ConcatenatingMediaSource(mediaSources[0], mediaSources[1])
}
}
In the else statement I get a failure as the return type is not a MediaSource, but a Unit. However, the commented code on the last line works fine. How do I modify the 2nd and 3rd last line to be able to play my list of songs?
Ok, so I just found this video: https://www.youtube.com/watch?v=svdq1BWl4r8
Turns out prepare
for ExoPlayer does not have to have a MediaSource
as a parameter, but can have a ConcatenatingMediaSource
as a parameter as well. These aren't the same but are both accepted by the prepare
function.
It's also worth noting that ConcatenatingMediaSource
can recieve a single MediaSource
. This means the if
statement check on the size of the MediaSource
ArrayList
isn't necessary.
The solution is therefore to change the return type of buildMediaSource
to ConcatenatingMediaSource
and remove the if statement. Like this:
private fun buildMediaSource(uris: ArrayList<Uri>): ConcatenatingMediaSource {
val userAgent = Util.getUserAgent(this, "MusicPlayer")
val defaultMediaSource = DefaultDataSourceFactory(this, userAgent)
val progressiveMediaSource = ProgressiveMediaSource.Factory(defaultMediaSource)
val mediaSources = ArrayList<MediaSource>()
for (uri in uris) {
mediaSources.add(progressiveMediaSource.createMediaSource(uri))
}
val concatenatingMediaSource = ConcatenatingMediaSource()
concatenatingMediaSource.addMediaSources(mediaSources)
return concatenatingMediaSource
}