ExoPlayer 2的质量选择器 [英] Quality selector for ExoPlayer 2

查看:199
本文介绍了ExoPlayer 2的质量选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个直播和电影播放器​​应用程序.我选择了 ExoPlayer版本2 来播放电影,对此我不太了解.我想让用户在播放器屏幕上选择电影的质量,例如720p或1080p等. 但是我不知道如何获取现有质量列表并将其显示给用户. 下面的代码是我对SimpleExoPlayer的实现:

I am currently developing a live and movie player application. I chose ExoPlayer version 2 to play the movie and I do not know much about it. I want to let the user choose the quality of a movie on the player screen, for example, 720p or 1080p or etc. But I do not know how to get a list of existing qualities and show them to the user. and the below code is my implementation of SimpleExoPlayer :

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() {

}

请帮助解决此问题. 非常感谢.

please help to solve this issue. thanks a lot.

推荐答案

您想要实现的所有功能都可以在ExoPlayer2中查看 PlayerActivity 类.

Everything you'd like to achieve is viewable in the ExoPlayer2 demo app. More specifically the PlayerActivity class.

您还可以查看此好文章关于该主题.

You can also check out this good article on the topic.

您要研究的核心点是围绕音轨选择(通过TrackSelector)和TrackSelectionHelper.我将在下面包含重要的代码示例,希望这些示例足以使您继续前进.但是最终,只要在演示应用程序中遵循类似的操作,您就可以到达所需的位置.

The core points you'll want to look into are around track selection (via the TrackSelector) as well as the TrackSelectionHelper. I'll include the important code samples below which will hopefully be enough to get you going. But ultimately just following something similar in the demo app will get you where you need to be.

您将保留使用其启动播放器的音轨选择器,并将其用于几乎所有内容.

You'll hold onto the track selector you init the player with and use that for just about everything.

下面只是一段代码,理想地涵盖了您要执行的操作的要点,因为该演示确实使头发变得过于复杂.另外我还没有运行代码,但是已经足够接近了.

Below is just a block of code to ideally cover the gist of what you're trying to do since the demo does appear to over-complicate things a hair. Also I haven't run the code, but it's close enough.

// 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来达到目的工作.

As I mentioned above, this is a slight oversimplification of the process, but the core part is that you're messing around with the TrackSelector, SelectionOverride, and Track/TrackGroups to get this to work.

您可以想像地按原样复制演示代码,它应该可以工作,但是我强烈建议您花时间了解每一部分的工作,并针对您的用例量身定制解决方案.

You could conceivably copy the demo code verbatim and it should work, but I'd highly recommend taking the time to understand what each piece is doing and tailor your solution to your use case.

如果我有更多的时间,我会编译和运行它.但是,如果您可以获取我的样本,请随时编辑我的帖子.

If I had more time I'd get it to compile and run. But if you can get my sample going then feel free to edit my post.

希望有帮助:)

这篇关于ExoPlayer 2的质量选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆