web-dev-qa-db-fra.com

Mise à jour de progression Mediaplayer à seekbar pas lisse?

Je travaille sur une application avec enregistreur et lecteur. J'utilise mediaplayer pour lire le fichier .wav enregistré et entre-temps, je souhaite effectuer une mise à jour vers une barre de recherche. Tout fonctionne bien Mais mon problème est que la progression de Mediaplayer ne fonctionne pas correctement. Si nous lisons un petit fichier, le pouce de la barre de recherche saute en secondes ou entre.

Est-ce que n'importe qui peut m'aider avec une solution de contournement pour le rendre lisse cherchant le progrès dans seekbar. Mon code est indiqué ci-dessous. Je suis bloqué ici.

    mediaPlayerIntiate();
    mediaPlayerSetSource();
    mMediaPlayer.start();
    task = new TimerTask() {
                @Override
                public void run() {
                    Graphbar.post(new Runnable() {
                        @Override
                        public void run() {

                            if (mMediaPlayer != null) {

                                if (playButtonState == MediaMode.PLAY) {
                                    if (mMediaPlayer.isPlaying()) {
                                        Graphbar.setProgress(mMediaPlayer
                                                .getCurrentPosition());
                                        mediaPlayerUpdateTimer(mMediaPlayer
                                                .getCurrentPosition());
                                        enableRewindandForward();
                                    }
                                }

                            }

                        }
                    });
                }
            };
            timer = new Timer();
            timer.schedule(task, 0, 8);
14
Sreedev R

mMediaPlayer.getCurrentPosition () Renvoie l'heure actuelle en millisecondes et vous mettez à jour cette action en Seekbar dont la capacité maximale est de 100. Créez une formule avec longueur de fichier et 100. essayez cette fonction

    MediaPlayer mMediaPlayer = new MediaPlayer();
    final SeekBar mSeelBar = new SeekBar(this);
    final int duration = mMediaPlayer.getDuration();
    final int amoungToupdate = duration / 100;
    Timer mTimer = new Timer();
    mTimer.schedule(new TimerTask() {

        @Override
        public void run() {
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    if (!(amoungToupdate * mSeelBar.getProgress() >= duration)) {
                        int p = mSeelBar.getProgress();
                        p += 1;
                        mSeelBar.setProgress(p);
                    }
                }
            });
        };
    }, amoungToupdate);

Et ce processus devrait être appelé lorsque le lecteur multimédia commence à jouer. à l'intérieur

mediaPlayer.setOnPreparedListener(new OnPreparedListener(){

    @Override
    public void onPrepared(MediaPlayer mp) {
    **// call here**
});

Mettre à jour

Mettre à jour 125 fois en quelques secondes n’est pas quelque chose que vous devriez faire. Veuillez augmenter votre intervalle pour mettre à jour SeekBar. J'ajoute cela après avoir lu les commentaires de NullPointer

19
Tofeeq
player.prepare(); // or start()

ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleWithFixedDelay(new Runnable()
{
  @Override
  public void run()
  {
    progressBar.setProgress(player.getCurrentPosition());
  }
}, 1, 1, TimeUnit.MICROSECONDS);
4
susemi99

Voici comment je gère le seekbar;

        mediaPlayer.setOnPreparedListener(new OnPreparedListener(){

        @Override
        public void onPrepared(MediaPlayer mp) {
            mediaPlayer.start();
            new SeekBarHandler().execute();
    });

Maintenant, j'ai une tâche asynchrone appelée SeekBarHandler qui gère la seekbar comme ceci:

    public class SeekBarHandler extends AsyncTask<Void, Void, Void> {

@Override
protected void onPostExecute(Void result) {
    Log.d("##########Seek Bar Handler ################","###################Destroyed##################");
    super.onPostExecute(result);
}

@Override
protected void onProgressUpdate(Void... values) {
    seekBar.setProgress(mediaPlayer.getCurrentPosition());
    super.onProgressUpdate(values);
}

@Override
protected Void doInBackground(Void... arg0) {
    while(mediaPlayer.isPlaying()&&isViewOn==true) {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    onProgressUpdate();
    }
    return null;
}

    }

Maintenant, dans mon onPause, je termine l'AsyncTask car cela n'a pas de sens de garder le thread en cours lorsque l'utilisateur ne peut pas voir la barre de recherche

    protected void onPause() {
    isViewOn=false;
    super.onPause();
    }

Et sur onResume je commence le AsyncTaskAgain comme ceci

    protected void onResume() {
    isViewOn=true;
    new SeekBarHandler().execute();
    super.onResume();
    }

Comme vous pouvez le voir, j'utilise un indicateur booléen isViewOn pour vérifier si la vue est activée ou non pour gérer la barre de recherche. 

4
Peshal

seekbar.setProgress () accepte uniquement int. Par conséquent, la plupart d’entre nous ont tendance à passer le pourcentage écoulé à cette méthode. Cependant, si vous avez besoin d'une progression beaucoup plus douce, vous pouvez utiliser la durée en millisecondes comme MAX. Ensuite, nous actualisons chaque milliseconde la progression de la barre de recherche. Vous trouverez ci-dessous un exemple que j'ai mis à jour toutes les 15 millisecondes, car presque tous les téléphones Android sont livrés avec un taux de rafraîchissement de 60 fps (images par seconde).

    try{
        mediaPlayer.start();
        seekbar.setProgress(0);
        seekbar.setMax(mediaPlayer.getDuration());

        // Updating progress bar
        seekHandler.postDelayed(updateSeekBar, 15);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }

/**
 * Background Runnable thread
 * */
private Runnable updateSeekBar = new Runnable() {
    public void run() {
        long totalDuration = mediaPlayer.getDuration();
        long currentDuration = mediaPlayer.getCurrentPosition();

        // Displaying Total Duration time
        remaining.setText(""+ milliSecondsToTimer(totalDuration-currentDuration));
        // Displaying time completed playing
        elapsed.setText(""+ milliSecondsToTimer(currentDuration));

        // Updating progress bar
        seekbar.setProgress((int)currentDuration);

        // Call this thread again after 15 milliseconds => ~ 1000/60fps
        seekHandler.postDelayed(this, 15);
    }
};

/**
 * Function to convert milliseconds time to
 * Timer Format
 * Hours:Minutes:Seconds
 * */
public String milliSecondsToTimer(long milliseconds){
    String finalTimerString = "";
    String secondsString = "";

    // Convert total duration into time
    int hours = (int)( milliseconds / (1000*60*60));
    int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
    int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
    // Add hours if there
    if(hours > 0){
        finalTimerString = hours + ":";
    }

    // Prepending 0 to seconds if it is one digit
    if(seconds < 10) {
        secondsString = "0" + seconds;
    }else {
        secondsString = "" + seconds;
    }

    finalTimerString = finalTimerString + minutes + ":" + secondsString;

    // return timer string
    return finalTimerString;
}
3
Hamzeen Hameem

Le problème que vous rencontrez a à voir avec la façon dont le SeekBar d'Android est conçu/implémenté Bien que cela fonctionne très bien, vous êtes limité par une combinaison de segments utilisés (par exemple, seekbar.setMax(int)) et par le temps de retard de votre gestionnaire.

Cela étant dit, j'ai sous-classé SeekBar pour créer mon propre SmoothSeekBar qui utilise ViewPropertyAnimators au lieu d'un gestionnaire.

Découvrez-le ici: https://github.com/Indatus/Android-SmoothSeekBar

0
jonstaff