前提条件:
语言:Kotlin
Exoplayer版本:2.18.5
需求: 给定一个 MV 资源文件,这个 MV 的资源文件中有两个音轨,一个是原唱的音轨,一个是伴唱的音轨,如何实现在播放的时候,这两个音轨之间的互相切换呢?
Exoplayer 在各个版本设置的 API 还并不是相同的,仅限我当前的版本,设置的代码如下:
fun setAudioTracks(exoPlayer: ExoPlayer, isSoloMode: Boolean) {
with(exoPlayer) {
val audioTracks = getAudioTracks()
val targetTrack = if (soloMode) audioTracks.firstOrNull() else audioTracks.lastOrNull()
targetTrack?.let {
trackSelectionParameters = trackSelectionParameters
.buildUpon()
.setOverrideForType(TrackSelectionOverride(it.trackGroup, it.trackIndex))
.build()
}
}
}
/**
* get all audio tracks from exoplayer
*
*/
fun ExoPlayer.getAudioTracks(): List<CbTrackFormat> {
val totalTrackFormats = mutableListOf<CbTrackFormat>()
for (i in 0 until currentTracks.groups.size) {
val item = currentTracks.groups[i]
for (j in 0 until item.length) {
val trackFormat = item.getTrackFormat(j)
totalTrackFormats.add(CbTrackFormat(trackFormat, item.mediaTrackGroup, j))
}
}
val audioTracks = totalTrackFormats.filter {
it.format.sampleMimeType?.startsWith("audio") == true
}
return audioTracks
}
data class CbTrackFormat(val format: Format, val trackGroup: TrackGroup, val trackIndex: Int)
如果需要在资源播放的时候就设置音轨,记得在播放器接收到 Player.STATE_READY 回调之后再进行设置即可,关于哪个音轨是伴奏哪个是原唱,需要和配置这个 MV 资源的人进行默认规定。
需求: 如果我给你两个 MP3 资源,一个是伴奏的 MP3 资源,一个是原唱的 MP3 资源,应该怎么切换呢? 这个需求主要是如何组装数据给到 Exoplayer, 把这两个 MP3 文件通过 MergingMediaSource 直接组装成一个资源给到播放器,然后调用上面的切换音轨的方法就可以做到。组装资源的代码如下:
fun mergeAudioSource(context: Context, mp3Source: String, musicSource: String): MediaSource {
val dataSourceFactory = DefaultDataSource.Factory(context)
// 此处后面有用
val extractorsFactory = DefaultExtractorsFactory()
val originalSongMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).createMediaSource(MediaItem.fromUri(mp3Source))
val accompanyMediaSource = ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory).createMediaSource(MediaItem.fromUri(musicSource))
val mergedMediaSource = MergingMediaSource(originalSongMediaSource, accompanyMediaSource)
return mergedMediaSource
}
-> Exoplayer#setMediaSource(mergedMediaSource) 即可.
即使做了上面所有的工作,并不是所有的资源都能切换原唱伴唱成功! 需要在调用这一行代码
extractorsFactory.setConstantBitrateSeekingEnabled(true)
具体原因也不知道,但是如果遇到切换音轨错误的话,设置一下这行代码看看是否有效果。