当前位置: 首页 > 知识库问答 >
问题:

ExoPlayer 2的质量选择器

公冶谦
2023-03-14
private void initPlayer(String path){
    Handler handler = new Handler();
    // 1. Create a default TrackSelector
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory =
            new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector =
            new DefaultTrackSelector(videoTrackSelectionFactory);

    // 2. Create a default LoadControl
    LoadControl loadControl = new DefaultLoadControl();
    // 3. Create the player
    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);

    SimpleExoPlayerView playerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
    playerView.setPlayer(player);
    playerView.setKeepScreenOn(true);
    // Produces DataSource instances through which media data is loaded.
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "ExoPlayer"));

    // This is the MediaSource representing the media to be played.
    MediaSource videoSource = new HlsMediaSource(Uri.parse(path),
            dataSourceFactory,handler, null);
    // Prepare the player with the source.
    player.addListener(this);
    player.prepare(videoSource);
    playerView.requestFocus();
    player.setPlayWhenReady(true); // to play video when ready. Use false to pause a video
}

// ExoPlayer Listener Methods :
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

}

@Override
public void onLoadingChanged(boolean isLoading) {

}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    switch (playbackState) {
        case ExoPlayer.STATE_BUFFERING:
            //You can use progress dialog to show user that video is preparing or buffering so please wait
            progressBar.setVisibility(View.VISIBLE);
            break;
        case ExoPlayer.STATE_IDLE:
            //idle state
            break;
        case ExoPlayer.STATE_READY:
            // dismiss your dialog here because our video is ready to play now
            progressBar.setVisibility(GONE);
            //Toast.makeText(getApplicationContext(),String.valueOf(player.getCurrentTrackSelections().get(0).getSelectedFormat().bitrate),Toast.LENGTH_SHORT).show();
            break;
        case ExoPlayer.STATE_ENDED:
            // do your processing after ending of video
            break;
    }
}

@Override
public void onPlayerError(ExoPlaybackException error) {
    // show user that something went wrong. it can be a dialog
}

@Override
public void onPositionDiscontinuity() {

}

请帮助解决这个问题。多谢.

共有1个答案

宣滨海
2023-03-14

你想要实现的一切都可以在ExoPlayer2演示应用程序中看到。更具体地说是PlayerActivity类。

你也可以看看这篇关于这个主题的好文章。

您需要研究的核心问题是轨道选择(通过TrackSelector)以及TrackSelectionHelper。我将在下面包括重要的代码示例,希望这些示例足以让您开始学习。但最终,只要在演示应用程序中遵循类似的内容,就会让你到达你需要的地方。

// 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);
 类似资料:
  • 我有一个mat select,其中的选项是数组中定义的所有对象。我试图将该值设置为其中一个选项的默认值,但是当页面呈现时,该值处于选中状态。 我的typescript文件包含: 我的HTML文件包含: 我已尝试将和

  • 启用ABR时,播放从选定的曲目开始,但快速跳到shaka player中的最低比特率曲目: 预期的 应选择轨道(轨道[id=14]),并在带宽可用时在同一轨道中继续。 我所尝试的 起初,我厌倦了设置abr。manifestparsed事件上的defaultBandwidthEstimate为1927692(磁道[id=14]),但它选择了下一个磁道(磁道[id=13])。所以我做了以下工作,以找到

  • 我已经在我的片段上实现了日期选择器,下面是代码: 我想使用material样式的DatePicker,我尝试使用这个库compile,但是结果是一样的。有什么帮助吗?我如何用材料日期选择器更改这个数据更新程序?谢谢

  • 我使用的是:Angular 4.4.5@Angular/Material:2.0.0-beta.12

  • 我想问我应该使用什么命令从mpd清单中选择视频质量? MPD清单链接 这里是mpd文件: 视频没有用DRM加密。当我尝试用FFmpeg下载时,成功了,但是FFmpeg自动选择了质量最差的(144p)。 我使用的FFmpeg命令: 来自ffmpeg的结果 试过youtube dl 注意:只需将(点)更改为

  • 如何在ExoPlayer2上设置字幕?我试过这个媒体来源: 但我犯了一个错误: