2017-08-23 3 views
2

Ich entwickle gerade eine Live- und Film-Player-Anwendung. Ich wählte ExoPlayer Version 2, um den Film zu spielen, und ich weiß nicht viel darüber. Ich möchte den Benutzer wählen lassen Qualität eines Films auf dem Player Bildschirm, zum Beispiel 720p oder 1080p oder etc. Aber ich weiß nicht, wie man eine Liste der vorhandenen Qualitäten und zeigen sie dem Benutzer. und der Code unten ist meine Implementierung von SimpleExoPlayer:Qualitätsselektor für 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() { 

} 

bitte helfen, dieses Problem zu lösen. vielen Dank.

Antwort

3

Alles, was Sie erreichen möchten, ist im ExoPlayer2 demo app sichtbar. Genauer gesagt die PlayerActivity Klasse.

Sie können dieses good article auf dem Thema auch heraus überprüfen.

Die Kernpunkte, die Sie untersuchen möchten, sind die Spurauswahl (über die TrackSelector) sowie die TrackSelectionHelper. Ich werde die wichtigen Codebeispiele darunter einfügen, die hoffentlich ausreichen werden, um Sie in Gang zu bringen. Aber letztendlich folgt nur etwas Ähnliches in der Demo-App, wo Sie hinkommen.

Sie halten an der Spurauswahl, mit der Sie den Player starten, und verwenden Sie diese für fast alles.

Unten ist nur ein Block von Code, um den Kern dessen, was Sie versuchen zu tun, ideal abzudecken, da die Demo scheint, Dinge ein Haar zu komplizieren. Auch ich habe den Code nicht ausgeführt, aber es ist nahe genug.

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

Wie ich bereits erwähnt, ist dies eine leichte Vereinfachung des Prozesses, aber der Kern ist, dass Sie Herumspielen mit dem TrackSelector, SelectionOverride und Track/TrackGroups zu bekommen dies funktioniert.

Sie könnten den Demo-Code wörtlich kopieren und es sollte funktionieren, aber ich würde sehr empfehlen, sich die Zeit zu nehmen, um zu verstehen, was jedes Stück macht und Ihre Lösung auf Ihren Anwendungsfall zuzuschneiden.

Wenn ich mehr Zeit hätte, würde ich es kompilieren und ausführen. Aber wenn Sie meine Probe erhalten können, dann zögern Sie nicht, meinen Beitrag zu bearbeiten.

Hoffe, dass hilft :)

+0

danke lieber @Kyle, das war wirklich hilfreich –

0

Ich vermeide den Weg wie oben geschrieben. Mein Weg ist mit dem DefaultTrackSelector wie folgt:

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

ich mit HLS Videos getestet haben und es scheint, in der richtigen Art und Weise auszuführen. Ich erhalte die Werte für Bitrate, Breite und Höhe aus dem HlsManifest.