用于mp4视频的Exoplayer视频质量选项

时间:2018-02-18 12:55:55

标签: mp4 hls exoplayer

我使用Exoplayer播放HLS视频轨道,以下代码可以正常工作以获取不同的可能视频质量,并将其显示为用户从多个分辨率中进行选择的选项。

for (int i = 0; i < player.getTrackCount(0); i++) {
            MediaFormat format = player.getTrackFormat(0, i);
            if (MimeTypes.isVideo(format.mimeType)) {
                if (format.adaptive) {
                    menu.add(1, (i + 1), (i + 1), "Auto");
                } else {
                    menu.add(1, (i + 1), (i + 1), format.width + "p");
                }
            }
        }

现在我对mp4视频轨道使用相同的代码,它没有给我一个选择的选项。默认情况下,只选择一种格式,不能再选择多种分辨率。

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

我希望this可以帮助您。

如果这不是答案,请忽略此答案。

我建议检查ExoPlayer的official demo

您要查看的核心要点是跟踪选择(通过TrackSelector)以及TrackSelectionHelper。我将在下面列出重要的代码示例,希望这些示例足以让您前进。但最终只需在演示应用程序中执行类似操作即可获得所需的位置。

您将保持启动播放器的轨道选择器,并将其用于几乎所有内容。

以下只是一段代码,理想地涵盖了您尝试做的事情的要点,因为演示看起来似乎使头发过于复杂。此外,我还没有运行代码,但它足够接近。

这是一个更多的描述。

我检查了解决方案here,我相信它会对你有帮助。

    // These two could be fields OR passed around
    int videoRendererIndex;
    TrackGroupArray trackGroups;

    // This is the body of the logic for see if there are even video tracks
    // It also does some field setting
    MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
    for (int i = 0; i < mappedTrackInfo.length; i++) {
      TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(i);
      if (trackGroups.length != 0) {
        switch (player.getRendererType(i)) {
          case C.TRACK_TYPE_VIDEO:
            videoRendererIndex = i;
            return true;
        }
      }
    }

    // This next part is actually about getting the list. It doesn't include
    // some additional logic they put in for adaptive tracks (DASH/HLS/SS),
    // but you can look at the sample for that (TrackSelectionHelper#buildView())
    // Below you'd be building up items in a list. This just does
    // views directly, but you could just have a list of track names (with indexes)
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
      TrackGroup group = trackGroups.get(groupIndex);
      for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
        if (trackIndex == 0) {
          // Beginning of a new set, the demo app adds a divider
        }
        CheckedTextView trackView = ...; // The TextView to show in the list
        // The below points to a util which extracts the quality from the TrackGroup
        trackView.setText(DemoUtil.buildTrackName(group.getFormat(trackIndex)));
    }

    // Assuming you tagged the view with the groupIndex and trackIndex, you
    // can build your override with that info.
    Pair<Integer, Integer> tag = (Pair<Integer, Integer>) view.getTag();
    int groupIndex = tag.first;
    int trackIndex = tag.second;
    // This is the override you'd use for something that isn't adaptive.
    override = new SelectionOverride(FIXED_FACTORY, groupIndex, trackIndex);
    // Otherwise they call their helper for adaptives, which roughly does:
    int[] tracks = getTracksAdding(override, trackIndex);
    TrackSelection.Factory factory = tracks.length == 1 ? FIXED_FACTORY : adaptiveTrackSelectionFactory;
    override = new SelectionOverride(factory, groupIndex, tracks);

    // Then we actually set our override on the selector to switch the quality/track
    selector.setSelectionOverride(rendererIndex, trackGroups, override);

正如我上面提到的,这个过程略微过于简单化,但核心部分是你正在弄乱TrackSelectorSelectionOverrideTrack / TrackGroups让它发挥作用。

您可以想象地逐字复制演示代码并且它应该可以工作,但我强烈建议您花时间了解每个部分正在做什么,并根据您的用例定制解决方案。