2017-08-23 135 views
2

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

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

} 

请帮助解决这个问题。 非常感谢。

你想实现

回答

3

一切都在ExoPlayer2 demo app可见。更具体地说是PlayerActivity类。

您也可以看看这个good article的话题。

您需要考虑的核心要点是选择曲目(通过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); 

正如我上面提到的,这是这个过程的一个轻微的过于简单,但核心部分是,你正在与TrackSelectorSelectionOverride乱搞,和Track/TrackGroups得到这个工作。

你可以想象逐字复制的演示代码,它应该工作,但我会强烈建议花时间了解每个部分所做的工作并定制的解决方案,以你的使用情况。

如果我有更多的时间,我会让它编译和运行。但是,如果你可以让我的样品去,然后随意编辑我的帖子。

希望能帮到:)

+0

谢谢亲爱的@凯尔,那真的很有帮助 –

0

我避开了上面的贴子。

trackSelector.setParameters(trackSelector.getParameters() 
          .withMaxVideoBitrate(bitrate) 
          .withMaxVideoSize(width, height)); 

我和HLS视频测试,它似乎在以正确的方式来执行:如下我的方法是使用DefaultTrackSelector。我从HlsManifest获得比特率,宽度和高度读数。