2017-08-23 7 views
2

Je suis actuellement en train de développer une application de lecture en direct et vidéo. J'ai choisi ExoPlayer version 2 pour jouer le film et je ne sais pas beaucoup à ce sujet. Je veux laisser l'utilisateur choisir la qualité d'un film sur l'écran du lecteur, par exemple, 720p ou 1080p ou etc. Mais je ne sais pas comment obtenir une liste des qualités existantes et les montrer à l'utilisateur. et le code ci-dessous est ma mise en œuvre de SimpleExoPlayer:Sélecteur de qualité pour 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() { 

} 

s'il vous plaît aider à résoudre ce problème. merci beaucoup.

Répondre

3

Tout ce que vous souhaitez obtenir est visible dans le ExoPlayer2 demo app. Plus précisément, la classe PlayerActivity. Vous pouvez également consulter cette good article sur le sujet.

Les points essentiels que vous voudrez examiner sont autour de la sélection de la piste (via le TrackSelector) ainsi que le TrackSelectionHelper. Je vais inclure ci-dessous les exemples de code importants qui, espérons-le, suffiront à vous aider. Mais finalement, juste après quelque chose de similaire dans l'application de démonstration vous obtiendrez où vous devez être.

Vous gardez le sélecteur de piste que vous avez avec le lecteur et utilisez-le pour à peu près tout. Ci-dessous est juste un bloc de code pour couvrir idéalement l'essentiel de ce que vous essayez de faire, car la démo semble trop compliquer les choses un cheveu. De plus, je n'ai pas exécuté le code, mais c'est assez proche.

// 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); 

Comme je l'ai mentionné ci-dessus, on constate une légère simplification excessive du processus, mais la partie de base est que vous déconner avec le pour obtenir ce travail TrackSelector, SelectionOverride et Track/TrackGroups.

Vous pourriez éventuellement copier le code de démonstration verbatim et cela devrait fonctionner, mais je vous recommande fortement de prendre le temps de comprendre ce que fait chaque pièce et d'adapter votre solution à votre cas d'utilisation.

Si j'avais plus de temps, je l'aurais compilé et exécuté. Mais si vous pouvez obtenir mon échantillon, n'hésitez pas à modifier mon message.

J'espère que ça aide :)

+0

merci cher @Kyle, c'était vraiment utile –

0

J'évite le chemin comme indiqué ci-dessus. Mon chemin utilise le DefaultTrackSelector comme suit:

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

Je l'ai testé avec des vidéos HLS et il semble faire de la bonne manière. J'obtiens le débit, la largeur et la hauteur du HlsManifest.