内置字幕在Flutter中是显示不了,因为它是一个SubtitleView,而flutter只获取一个textureview,所以字幕出不来.也不会有回调.
在这种情况下,回调也收不到,懒的研究了.
前一篇已经说过了,字幕的样式修改,这些只能小修改.
就不作详细的说明了.
class TrackInformation {
public static int TYPE_DOWNLOAD_TRACK = -3;
//轨道类型,如果-2:选择轨道,-1:关闭轨道
public static int TYPE_SELECT_TRACK = -2;
public static int TYPE_NO_TRACK = -1;
public static int TYPE_TRACK = -0;
public int type = TYPE_TRACK;
/**
* 这个是渲染器索引,音频,字幕都是渲染器,当前不用它
*/
public int trackIndex;
public String trackName;
/**
* 这个是音频的索引,外部传来的值trackId应该是对应这个值的
*/
public int trackGroupIndex;
public Tracks.Group trackGroup;
public boolean isSelected;
//vlc trackid
public String id;
//这是exo用的
public TrackInformation(Tracks tracks, int trackGroupIndex, int trackIndex, String trackName, int type) {
this.trackIndex = trackIndex;
this.trackName = trackName;
this.trackGroupIndex = trackGroupIndex;
this.type = type;
if (null != tracks) {
trackGroup = tracks.getGroups().get(trackGroupIndex);
isSelected = trackGroup.isSelected(); //初始化时需要设置一下.
}
}
//这是vlc用的
public TrackInformation(String id, int type, int trackIndex, String trackName, boolean isSelected) {
this.id = id;
this.type = type;
this.trackIndex = trackIndex;
this.trackName = trackName;
this.isSelected = isSelected;
}
}
然后加载出字幕轨道:
fun getAllTracks(): ArrayList {
val alltrakcs = arrayListOf()
val tracks = mExoPlayer!!.currentTracks
val supportInformations: List =
gatherSupportedTrackInfosOfType(tracks, trackType)
if (supportInformations != null && supportInformations.size > 0) {
val postfix = if (C.TRACK_TYPE_AUDIO == trackType) {
getString(R.string.player_track_track_audio)
} else {
getString(R.string.player_track_track_subtitle)
}
if (C.TRACK_TYPE_TEXT == trackType) {
var selectTrack =
TrackInformation(
null, 0, 0,
String.format(
"%s%s",
getString(R.string.player_track_track_select),
postfix
),
TrackInformation.TYPE_SELECT_TRACK
)
alltrakcs.add(selectTrack)
selectTrack =
TrackInformation(
null, 0, 0,
getString(R.string.player_track_subtitle_download_title),
TrackInformation.TYPE_DOWNLOAD_TRACK
)
alltrakcs.add(selectTrack)
}
val closeTrack =
TrackInformation(
null, 0, 0,
String.format("%s%s", getString(R.string.player_track_track_close), postfix),
TrackInformation.TYPE_NO_TRACK
)
alltrakcs.add(closeTrack)
alltrakcs.addAll(supportInformations)
} else {
if (C.TRACK_TYPE_TEXT == trackType) {
var selectTrack = TrackInformation(
null,
0,
0,
getString(R.string.player_track_track_load_subtitle),
TrackInformation.TYPE_SELECT_TRACK
)
alltrakcs.add(selectTrack)
selectTrack =
TrackInformation(
null, 0, 0,
getString(R.string.player_track_subtitle_download_title),
TrackInformation.TYPE_DOWNLOAD_TRACK
)
alltrakcs.add(selectTrack)
}
}
return alltrakcs
}
轨道中,字幕与音频是一样地.
获取到了字幕列表,显示就比较简单了,不贴代码了.用recyclerview,自己处理选中的状态
选中轨道
fun selectTrack(subtitleId: String?, mExoPlayer: ExoPlayer?, tracks: Tracks) {
val trackGroups = tracks.groups
for (groupIndex in trackGroups.indices) {
val trackGroup = trackGroups[groupIndex]
for (trackIndex in 0 until trackGroup.length) {
val format = trackGroup.getTrackFormat(trackIndex)
if (format.id == subtitleId) {
val indexs: MutableList = ArrayList()
indexs.add(0)
val trackSelectionParameters: TrackSelectionParameters =
mExoPlayer!!.trackSelectionParameters
Util.castNonNull(mExoPlayer).trackSelectionParameters =
trackSelectionParameters
.buildUpon()
.setOverrideForType(
TrackSelectionOverride(
trackGroup.mediaTrackGroup,
indexs
)
)
.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false)
.build()
Timber.d("selectTrack:$subtitleId, $trackGroup")
break
}
}
}
}
音频与字幕是一样的
它是通过trackSelectionParameters,来设置其中的trackgroup索引实现的.
如果要关闭字幕:
val trackSelectionParameters: TrackSelectionParameters =
mExoPlayer!!.trackSelectionParameters
Util.castNonNull(mExoPlayer).trackSelectionParameters =
trackSelectionParameters
.buildUpon()
.clearOverridesOfType(trackType)
.setTrackTypeDisabled(trackType, true)
.build()
//下面是列表中处理一下选中的状态
updateSelection(index, trackInformations)
外挂字幕不能在播放中流畅地加载,需要重新初始化,官方已经回复过了.那么外挂字幕的展示有两种方式,一种是让播放器启动时加载,或者播放中加载后重新初始化.另一种是自己实现加载与展示.
在播放中加载,比如从文件中选择.exo支持格式有限,直接进入选择.
然后设置一个标志位,在回调中根据这个来处理选中的字幕
readyToSelectTrack = true
override fun onTracksChanged(tracks: Tracks) {
if (readyToSelectTrack) {
if (null != mediaItem && mediaItem!!.localConfiguration != null) {
val subtitles =
mediaItem!!.localConfiguration!!.subtitleConfigurations
Timber.d("onTracksChanged.subtitles:$subtitles")
if (subtitles.size > 0) {
val cfg = subtitles[subtitles.size - 1]
ExoTracksViewHolder.selectTrack(cfg.id, mExoPlayer, tracks)
}
}
readyToSelectTrack = false
}
}
这里的selectTrack方法是处理字幕轨道的选中.当然首先保证字幕可加载,并且成功了.
字幕不处理选中,则不会展示,默认会用语言对应的字幕加载.
外置字幕处理解析,展示就比较麻烦了,这里不多介绍 ,可以参考tvbox的字幕实现
tvbox的字幕部分已经抽离,作了些修改.exoplayer不让非ui线程访问的也作了修改了,GitHub - archko/subtitle