Android 如何在Exoplayer中打开/关闭HLS流式URL中的闭路字幕?

Android 如何在Exoplayer中打开/关闭HLS流式URL中的闭路字幕?,android,exoplayer,Android,Exoplayer,我正在使用Exoplayer 2.0.4版来播放HLS流(.m3u8)。“我的HLS流”包含与其一起的闭合标题。如何使用exoplayer控制闭路字幕?是否可以在需要时隐藏/显示字幕,并在需要时更改字幕布局的位置?我能够使用DefaultTrackSelector控制ExoPlayer 2中的字幕选择。下面的代码是根据ExoPlayer 2演示的类修改的,更多的实现细节应该参考该类 要关闭字幕,需要禁用文本轨迹的渲染器并清除选择覆盖 trackSelector.setRendererDisabl

我正在使用Exoplayer 2.0.4版来播放HLS流(.m3u8)。“我的HLS流”包含与其一起的闭合标题。如何使用exoplayer控制闭路字幕?是否可以在需要时隐藏/显示字幕,并在需要时更改字幕布局的位置?

我能够使用
DefaultTrackSelector
控制ExoPlayer 2中的字幕选择。下面的代码是根据ExoPlayer 2演示的类修改的,更多的实现细节应该参考该类

要关闭字幕,需要禁用文本轨迹的渲染器并清除选择覆盖

trackSelector.setRendererDisabled(TRACK_TEXT, true);
trackSelector.clearSelectionOverrides();
TRACK\u TEXT
是我创建的一个局部静态变量,表示与视频/音频曲目相关的文本曲目(2)的索引。我相信SelectionOverrides只是通过编程指定的曲目选择

要再次启用曲目,您需要为文本曲目启用渲染器,然后为所需的文本曲目设置新的
SelectionOverride
。在执行此操作之前,需要从
DefaultTrackSelector
获取当前映射的文本曲目的
TrackGroupArray

MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
TrackGroupArray textGroups = mappedTrackInfo.getTrackGroups(TRACK_TEXT); // list of captions
int groupIndex = 1; // index of desired caption track within the textGroups array

trackSelector.setRendererDisabled(TRACK_TEXT, false);
MappingTrackSelector.SelectionOverride override = 
    new MappingTrackSelector.SelectionOverride(fixedFactory, groupIndex, 0);
trackSelector.setSelectionOverride(TRACK_TEXT, textGroups, override);
有关更多实现细节(例如,初始化trackSelector和fixedFactory),请查看

您可以使用
字幕视图
在版面中定位字幕。您的类需要实现
TextRenderer.Output
并重写
oncus()
方法

@Override
public void onCues(List<Cue> cues) {
    if (subtitleView != null) {
        subtitleView.onCues(cues);
    }
}
@覆盖
公共void onCues(列表提示){
如果(子标题视图!=null){
subtitleView.oncuses(提示);
}
}

在我的应用程序中,我初始化
轨迹选择器,如下所示

关闭视频曲目的近距离字幕

trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
            .setRendererDisabled(C.TRACK_TYPE_VIDEO, true)
            .build()
    );
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
            .setRendererDisabled(C.TRACK_TYPE_VIDEO, false)
            .build()
    );
打开视频曲目的近距离字幕

trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
            .setRendererDisabled(C.TRACK_TYPE_VIDEO, true)
            .build()
    );
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    trackSelector.setParameters(new DefaultTrackSelector.ParametersBuilder()
            .setRendererDisabled(C.TRACK_TYPE_VIDEO, false)
            .build()
    );

将ExoPlayer库更新为后

implementation 'com.google.android.exoplayer:exoplayer:2.9.5'
我发现
MappingTrackSelector.SelectionOverride
方法不再存在

我找不到一个可行的替代方案,因为只是用
DefaultTrackSelector替换。SelectionOverride
对我不起作用,而且在我的视频中没有播放字幕

MediaSource mediaSource =  new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
最后一组对我有用的行:

TrackGroupArray trackGroups = trackSelector.getCurrentMappedTrackInfo().getTrackGroups(newSubtitle.renderIndex);

DefaultTrackSelector.ParametersBuilder paramsBuilder = trackSelector.buildUponParameters();

DefaultTrackSelector.SelectionOverride sOverride = new DefaultTrackSelector.SelectionOverride(newSubtitle.groupIndex, newSubtitle.indexWithinGroup);

boolean isDisabled = trackSelector.getParameters().getRendererDisabled(newSubtitle.renderIndex);

paramsBuilder.setRendererDisabled(newSubtitle.renderIndex, isDisabled);

if (sOverride != null) {
    paramsBuilder.setSelectionOverride(newSubtitle.renderIndex, trackGroups, sOverride);
} else {
    paramsBuilder.clearSelectionOverrides(newSubtitle.renderIndex);
}

trackSelector.setParameters(paramsBuilder);
旧代码是:

TrackGroupArray trackGroups = trackSelector.getCurrentMappedTrackInfo().getTrackGroups(newSubtitle.renderIndex);

MappingTrackSelector.SelectionOverride sOverride = new MappingTrackSelector.SelectionOverride(
    new FixedTrackSelection.Factory(), 
    newSubtitle.groupIndex, 
    newSubtitle.indexWithinGroup
);

trackSelector.setSelectionOverride(newSubtitle.renderIndex, trackGroups, sOverride);
trackSelector.setRendererDisabled(newSubtitle.renderIndex, false);
关闭字幕:

DefaultTrackSelector.ParametersBuilder paramsBuilder=trackSelector.buildUponParameters();
paramsBuilder.setRenderDisabled(playingSubtitle.renderIndex,true);
trackSelector.setParameters(paramsBuilder);

要禁用曲目,比如字幕(文本)曲目,您需要使用先前传递给
ExoPlayerFactory.newSimpleInstance
DefaultTrackSelector,要禁用曲目,您需要其渲染器索引。在选择ExoPlayer中的曲目时,实际上有两个令人困惑的术语(至少对我来说!),一个是TrackType,另一个是renderindex。基本上有一些曲目类型可以在com.google.android.exoplayer2.C类中访问,主要有曲目类型音频曲目类型视频曲目类型文本。但是另一方面,renderindex可以是从0开始的任何数字(我猜)。所以要禁用轨迹,首先需要找到它的渲染器索引。然后使用下面的代码禁用轨迹:

trackSelector
            ?.buildUponParameters()
            ?.setRendererDisabled(rendererIndex, true)
            ?.let {
                trackSelector?.setParameters(it)
            }

Xamarin.Android的解决方案:

[Obsolete]
private DefaultTrackSelector CreateTrackSelector()
{
    var bandwidthMeter = new DefaultBandwidthMeter();
    var videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    var trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    var trackParameter = new DefaultTrackSelector.ParametersBuilder()
         // disables closed caption / subtitle
        .SetDisabledTextTrackSelectionFlags(C.TrackTypeText)
        .Build();
    trackSelector.SetParameters(trackParameter);
    return trackSelector;
}

我强烈建议不要使用常量
TRACK\u TEXT
C.TRACK\u TYPE\u TEXT
,因为:

trackSelector.setRendererDisabled(TRACK_TEXT, true);
trackSelector.clearSelectionOverrides();
由于它可能因您使用的资产而异,因此您可以确保使用以下代码(Kotlin版本)禁用正确的渲染器:


嗨,拉姆,你能成功地显示字幕吗?如果是这样,您能否与Exoplayer版本2共享代码以添加字幕?感谢Exoplayer,我能够通过在github项目中使用SimpleExoplayer视图类来定制封闭式字幕。您可以隐藏/显示、更改标题文本字体、颜色、位置…@RamJay您可以显示/隐藏字幕吗?我还设法在Exoplayer中显示字幕,但现在想打开/关闭它们。如何做到这一点?在哪里以及如何将字幕Uri/链接传递到此代码?@SamRamezanli有关如何创建媒体源和准备播放机的信息,请参见此处:我们使用HLS,因此文本和视频曲目都包含在一个清单/url中。进一步的实现细节基于Thank@Taylor,但我使用DASH,我需要将字幕链接到视频。但是,我目前在您共享的链接中使用相同的解决方案,此方法不允许我们启用和禁用字幕,除非我们释放并重新启动播放器。我有@Sam Ramezanli提到的相同问题,我有一个场景,如切换到下一个剪辑时,上一个视频的关闭字幕将显示在当前剪辑中。我可以知道如何控制这类问题。对我来说,这个答案不起作用。我使用的是exoplayer 2.7.1版,就像一个charmyou可能需要设置首选语言。你从哪里获得
newSubtitle
?你的答案很好,但newSubtitle是错误的。但是我没有投反对票。。