wake-up-neo.com

Mediaplayer-Fortschrittsupdate auf Suchleiste nicht reibungslos?

Ich arbeite an einer App mit Recorder und Player. Ich benutze den Mediaplayer, um die aufgezeichnete .wav-Datei abzuspielen und möchte in der Zwischenzeit auf eine Suchleiste updaten. Alles funktioniert gut, aber mein Problem ist, dass die Aktualisierung des Mediaplayer-Fortschritts auf der Suchleiste nicht reibungslos verläuft. Wenn wir eine kleine Datei abspielen, springt der Daumen der Suchleiste in Sekunden oder dazwischen.

Kann mir jemand bei einer Problemumgehung helfen, um das reibungslose Suchen des Fortschritts bei seekbar zu erleichtern. Mein Code wird unten gezeigt. Ich stecke hier fest.

    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 () Gibt die aktuelle Zeit in Millisekunden zurück und aktualisiert diese in Seekbar. Die maximale Kapazität beträgt 100. Erstellen Sie eine Formel mit Länge der Datei und 100. Versuchen Sie diese Funktion

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

Dieser Vorgang sollte aufgerufen werden, wenn der Media Player abgespielt wird. Innerhalb

mediaPlayer.setOnPreparedListener(new OnPreparedListener(){

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

Update

125 mal in Sekunden aktualisieren, sollten Sie nicht tun. Bitte verlängern Sie Ihr Intervall für die Aktualisierung von SeekBar. Ich füge dies nach dem Lesen von Kommentaren von NullPointer hinzu

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

So geh ich mit der Suchleiste um;

        mediaPlayer.setOnPreparedListener(new OnPreparedListener(){

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

Jetzt habe ich eine Async-Task namens SeekBarHandler, die die Suchleiste wie folgt behandelt:

    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;
}

    }

Jetzt in meiner onPause beende ich die AsyncTask, da es keinen Sinn macht, den Thread am Laufen zu halten, wenn der Benutzer die Suchleiste nicht sehen kann

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

Und bei onResume starte ich das AsyncTaskAgain so

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

Wie Sie sehen, verwende ich ein boolesches Flag isViewOn, um zu prüfen, ob die Ansicht aktiviert ist oder nicht, um die Suchleiste zu behandeln. 

4
Peshal

seekbar.setProgress () akzeptiert nur int. Daher neigen die meisten von uns dazu, den verstrichenen Prozentsatz auf diese Methode zu übertragen. Wenn Sie jedoch eine wesentlich glattere Progression benötigen, können Sie die Dauer in Millisekunden als MAX verwenden. Dann aktualisieren wir den Fortschritt der Suchleiste jede Millisekunde. Unten ist ein Beispiel, und ich habe es jede 15. Millisekunde aktualisiert, da fast jedes Android-Handy mit einer Bildwiederholfrequenz von 60 Bildern pro Sekunde (Frames pro Sekunde) ausgestattet ist.

    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

Das Problem, das Sie haben, hat mit der Art und Weise zu tun, wie Android SeekBar entworfen/implementiert wird. Während es sehr gut funktioniert, sind Sie durch eine Kombination von verwendeten Segmenten (d. H. seekbar.setMax(int)) und die Verzögerungszeit Ihres Handlers eingeschränkt.

Davon abgesehen, habe ich SeekBar in eine Klasse unterteilt, um meine eigene SmoothSeekBar zu erstellen, die ViewPropertyAnimators anstelle eines Handlers verwendet.

Überprüfen Sie es hier: https://github.com/Indatus/Android-SmoothSeekBar

0
jonstaff