Android ExoPlayer onProgressChanged

Comment puis-je surveiller les changements de progression sur ExoPlayer?

J'ai essayé de mettre en œuvre un caché MediaController et en remplaçant setOnSeekBarChangeListener méthodes, mais pour l'instant sans succès. Je me demande s'il existe une autre façon d'écouter de la ExoPlayer progrès.

18
demandé sur Alexandar G 2015-02-18 21:10:00

9 réponses

je sais que cette question est très ancienne. Mais, j'ai atterri sur ce tout en mettant en œuvre ExoPlayer. C'est qui aideront les autres à faire de même plus tard:)

Donc, j'ai suivi les méthodes suivantes pour suivre la progression de la lecture. C'est la manière dont c'est fait dans le ExoPlayer Google Docs. Il travaille en tant que de besoin.

Caisse PlayerControlView.javaGoogle ExoPlayer repository

updateProgressBar() est la fonction pour mettre à jour le SeekBar progrès:

private void updateProgressBar() {
    long duration = player == null ? 0 : player.getDuration();
    long position = player == null ? 0 : player.getCurrentPosition();
    if (!dragging) {
        mSeekBar.setProgress(progressBarValue(position));
    }
    long bufferedPosition = player == null ? 0 : player.getBufferedPosition();
    mSeekBar.setSecondaryProgress(progressBarValue(bufferedPosition));
    // Remove scheduled updates.
    handler.removeCallbacks(updateProgressAction);
    // Schedule an update if necessary.
    int playbackState = player == null ? Player.STATE_IDLE : player.getPlaybackState();
    if (playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED) {
        long delayMs;
        if (player.getPlayWhenReady() && playbackState == Player.STATE_READY) {
            delayMs = 1000 - (position % 1000);
            if (delayMs < 200) {
                delayMs += 1000;
            }
        } else {
            delayMs = 1000;
        }
        handler.postDelayed(updateProgressAction, delayMs);
    }
}

private final Runnable updateProgressAction = new Runnable() {
    @Override
    public void run() {
        updateProgressBar();
    }
};

Nous appelons updateProgressBar() à l'intérieur de updateProgressAction jusqu'à ce que la lecture s'arrête. La fonction est appelée la première fois chaque fois qu'il y a un changement d'état. Nous utilisons removeCallbacks(Runnable runnable) pour qu'il y en ait toujours un updateProgressAction soucier.

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
  updateProgressBar();
}

J'espère que cela vous aidera!

11
répondu Ankit Aggarwal 2018-09-11 11:28:56

Je ne suis pas sûr que ce soit la meilleure façon, mais j'y suis arrivé en surchargeant le TrackRenderer.

j'utilise videoPlayer.getBufferedPercentage(), mais vous pourriez être en mesure de calculer le pourcentage vous-même ainsi, en utilisant juste TrackRenderergetBufferedPositionUs() et getDurationUs()

public interface ProgressListener {
    public void onProgressChange(long progress);
}

public class CustomVideoRenderer extends  MediaCodecVideoTrackRenderer {

    long progress = 0;
    private final CopyOnWriteArraySet<ProgressListener> progressListeners = new CopyOnWriteArraySet();

    // [...]
    // Skipped constructors
    // [...]

    public void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
        super.doSomeWork(positionUs, elapsedRealtimeUs);

        long tmpProgress = videoPlayer.getBufferedPercentage();

        if (tmpProgress != this.progress) {
            this.progress = tmpProgress;

            for (ProgressListener progressListener : this.progressListeners) {
                progressListener.onProgressChange(progress);
            }
        }
    }

    public void addProgressListener(ProgressListener listener) {
        this.progressListeners.add(listener);
    }

}
3
répondu Nezo 2015-06-02 07:00:46

cela fonctionne au moins avec Exoplayer 2.

il y a quatre états de lecture: STATE_IDLE, STATE_BUFFERING, STATE_READY et STATE_ENDED.

vérifier l'état de lecture est facile à faire. Il y a au moins deux solutions: if-statement ou switch-statement.

quel que soit l'état de lecture en cours, vous pouvez exécuter votre méthode ou définir quelque chose d'autre par exemple progressbar.

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if (playbackState == ExoPlayer.STATE_ENDED) {
        showControls();
        Toast.makeText(getApplicationContext(), "Playback ended", Toast.LENGTH_LONG).show();
    }
    else if (playbackState == ExoPlayer.STATE_BUFFERING)
    {
        progressBar.setVisibility(View.VISIBLE);
        Toast.makeText(getApplicationContext(), "Buffering..", Toast.LENGTH_SHORT).show();
    }
    else if (playbackState == ExoPlayer.STATE_READY)
    {
        progressBar.setVisibility(View.INVISIBLE);
    }

}
2
répondu user7459244 2017-01-23 19:47:33

pour être clair, il n'y a pas de build in EventListener pour l'événement progress, mais vous pouvez appeler Handler.postDelayed à l'intérieur de la fonction updateProgress() pour obtenir la progression actuelle

 private void updateProgress(){

    //get current progress 
    long position = player == null ? 0 : player.getCurrentPosition();
    //updateProgress() will be called repeatedly, you can check 
    //player state to end it
    handler.postDelayed(updateProgressAction,1000)

}

 private final Runnable updateProgressAction = new Runnable() {
    @Override
    public void run() {        
      updateProgress();
    }
};

pour plus de détails, voir la source de PlaybackControlView.java à l'intérieur de Exoplayer

2
répondu ufxmeng 2017-05-10 00:25:53

essaie Juste de faire ceci, de son travail pour moi :

handler = new Handler();
runnable = new Runnable() {
      @Override
      public void run() {
           progressbar.setProgress((int) ((exoPlayer.getCurrentPosition()*100)/exoPlayer.getDuration()));
           handler.postDelayed(runnable, 1000);
      }
};
handler.postDelayed(runnable, 0);

Ici

  • getCurrentPosition(): renvoie la position de lecture courante en millisecondes.