如何在HLS流媒体上打开/关闭封闭字幕



我正在使用 exoplayer版本2.0.4 播放 hls streams (。m3U8)。我的HLS流包含封闭的标题。如何用系计性字幕控制封闭的字幕?需要在需要时隐藏/显示字幕并在需要时更改字幕布局的位置是否可行?

我能够使用 DefaultTrackSelector在exoplayer 2中选择字幕选择。下面的代码是根据Exoplayer 2演示的TrackSelectionHelper类修改的,该类别应引用以获取更多实施详细信息。

要关闭字幕,您需要禁用渲染器以获取文本轨道并清除选择覆盖。

trackSelector.setRendererDisabled(TRACK_TEXT, true);
trackSelector.clearSelectionOverrides();

TRACK_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),请查看Exoplayer 2演示。

您可以使用SubtitleView将字幕定位在布局中。您的班级将需要实现TextRenderer.Output并覆盖onCues()方法。

@Override
public void onCues(List<Cue> cues) {
    if (subtitleView != null) {
        subtitleView.onCues(cues);
    }
}

在我的应用程序中,我初始化trackselecktor如下

关闭视频曲目

的密闭字幕
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()
    );

我强烈建议不要使用常量的TRACK_TEXTC.TRACK_TYPE_TEXT

trackSelector.setRendererDisabled(TRACK_TEXT, true);
trackSelector.clearSelectionOverrides();

因为它可能会有所不同取决于您使用的资产,因此您可以确保使用以下代码(Kotlin版本)禁用正确的渲染器:

  private fun disableSubtitles(){
    (0 until (trackSelector.currentMappedTrackInfo?.rendererCount ?: 0)).filter {position ->
      player.getRendererType(position) == C.TRACK_TYPE_TEXT
    }.map {position ->
      trackSelector.parameters = trackSelector.buildUponParameters()
          .setRendererDisabled(position,true)
          .clearSelectionOverrides(position)
          .build()
    }
  }

在将外层库更新为

之后
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.setRendererDisabled(playingSubtitle.renderIndex, true);
trackSelector.setParameters(paramsBuilder);

要禁用轨道,假设字幕(文本)曲目,您需要使用 defaultTrackSelector 您已经传递给ExoPlayerFactory.newSimpleInstance您需要它的 RendererIndex 。在选择 exoplayer 中的曲目时,实际上有两个令人困惑(至少对我来说!),一个是 tracktype ,而另一个是 RenderererIndex 基本上,有一些曲目类型可以在 com.google.android.exoplayer.2.c 类中访问,主要的曲目是 track_type_type_audio track_s> track_type_vide_video track_type_text 。但是 RendererIndex 另一方面可以是从0开始的任何数字(我猜)。因此,要禁用轨道,您需要首先找到它的RendererIndex。然后使用下面的代码禁用曲目:

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;
}

最新更新