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.
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.java
Google 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!
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 TrackRenderer
getBufferedPositionUs()
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);
}
}
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);
}
}
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
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.