exoplayer的使用-5,字幕(内,外)

内置字幕在Flutter中是显示不了,因为它是一个SubtitleView,而flutter只获取一个textureview,所以字幕出不来.也不会有回调.

在这种情况下,回调也收不到,懒的研究了.

1.实现内置字幕,普通的StyledPlayerView里面就有,布局的时候加上就行了.


    

    

前一篇已经说过了,字幕的样式修改,这些只能小修改.

就不作详细的说明了.

2.字幕的加载.显示.如果我不用系统的,我就需要自己定义一个了.
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
    }

轨道中,字幕与音频是一样地.

3.显示出内置字幕列表

获取到了字幕列表,显示就比较简单了,不贴代码了.用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)
4.外挂字幕

外挂字幕不能在播放中流畅地加载,需要重新初始化,官方已经回复过了.那么外挂字幕的展示有两种方式,一种是让播放器启动时加载,或者播放中加载后重新初始化.另一种是自己实现加载与展示.

在播放中加载,比如从文件中选择.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

你可能感兴趣的:(android,ffmpeg,exoplayer)