SeekBar et Media player dans android

j'ai un simple lecteur et enregistreur. Tout fonctionne très bien, mais avoir un problème. Je veux ajouter la barre de chercher pour voir les progrès dans la lecture de disque et d'utiliser cette barre de chercher pour mettre la place du joueur devrait jouer. Je n'ai pas de progrès, mais sans effet. C'est le code:

package com.example.recorder;

import java.io.IOException;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends Activity implements OnSeekBarChangeListener
{
    private static final String LOG_TAG = "AudioRecordTest";
    private static String mFileName = null;
    private SeekBar seekBar;
    private MediaRecorder mRecorder = null;
    private Button startRecord, startPlaying, stopPlaying;
    private MediaPlayer   mPlayer = null;

    private void onRecord(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }
    }



    private void startPlaying() {
        if(mPlayer != null && mPlayer.isPlaying()){
            mPlayer.pause();
        } else if(mPlayer != null){
            mPlayer.start();
        }else{
        mPlayer = new MediaPlayer();
        try {

            mPlayer.setDataSource(mFileName);
            mPlayer.prepare();
            mPlayer.start();

        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
        }

    }

    private void stopPlaying() {
        mPlayer.release();
        mPlayer = null;
        startPlaying.setText("Start playing");
    }

    private void pausePlaying(){
        if(mPlayer.isPlaying()){
            mPlayer.pause();
        } else {
          mPlayer.start();
        }
    }

    private void startRecording() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {
            mRecorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }

        mRecorder.start();
    }

    private void stopRecording() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }



    public MainActivity() {
        mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
        mFileName += "/audiorecordtest.3gp";
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        setContentView(R.layout.activity_main);

        startPlaying = (Button) findViewById(R.id.buttonStartPlay);
        stopPlaying = (Button) findViewById(R.id.buttonStopPlaying);
        startRecord = (Button) findViewById(R.id.buttonStartRecord);
        seekBar = (SeekBar) findViewById(R.id.seekBar);

        startRecord.setOnClickListener(new OnClickListener() {
            boolean mStartRecording = true;
            @Override
            public void onClick(View v) {
                onRecord(mStartRecording);
                if (mStartRecording) {
                    startRecord.setText("Stop recording");
                } else {
                    startRecord.setText("Start recording");
                }
                mStartRecording = !mStartRecording;

            }
        });  


        startPlaying.setOnClickListener(new OnClickListener() {
            boolean mStartPlaying = true;
            @Override
            public void onClick(View v) {
                //onPlay(mStartPlaying);
                startPlaying();
                if (mStartPlaying) {
                    startPlaying.setText("Stop playing");
                } else {
                    startPlaying.setText("Start playing");
                }
                mStartPlaying = !mStartPlaying;
            }
        });

        stopPlaying.setOnClickListener(new OnClickListener() {
            boolean mStartPlaying = true;
            @Override
            public void onClick(View v) {
                 stopPlaying();

            }
        });


    }

    @Override
    public void onPause() {
        super.onPause();
        if (mRecorder != null) {
            mRecorder.release();
            mRecorder = null;
        }

        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }



    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        if(fromUser){
            mPlayer.seekTo(progress); 
            seekBar.setProgress(progress);
            }
            else{
             // the event was fired from code and you shouldn't call player.seekTo()
            }

    }



    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }



    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }
}

quelques idées comment utiliser seek bar pour voir le progrès et la place de l'enregistrement devrait jouer?

43
demandé sur M.G 2013-06-18 15:55:34

11 réponses

pour créer une 'connexion' entre SeekBar et MediaPlayer vous devez d'abord obtenir votre durée maximale d'enregistrement actuelle et la définir à votre barre de recherche.

mSeekBar.setMax(mFileDuration); // where mFileDuration is mMediaPlayer.getDuration();

après avoir initialisé votre MediaPlayer et par exemple appuyer sur le bouton play, vous devez créer handler et post runnable pour que vous puissiez mettre à jour votre SeekBar (dans le UI thread lui-même) avec la position actuelle de votre MediaPlayer comme ceci:

private Handler mHandler = new Handler();
//Make sure you update Seekbar on UI thread
MainActivity.this.runOnUiThread(new Runnable() {

    @Override
    public void run() {
        if(mMediaPlayer != null){
            int mCurrentPosition = mMediaPlayer.getCurrentPosition() / 1000;
            mSeekBar.setProgress(mCurrentPosition);
        }
        mHandler.postDelayed(this, 1000);
    }
});

et mettre à jour cette valeur à chaque seconde.

si vous avez besoin de mettre à jour la position du MediaPlayer pendant que l'utilisateur fait glisser votre SeekBar vous devez ajouter OnSeekBarChangeListener à votre SeekBar et le faire là:

        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                
                if(mMediaPlayer != null && fromUser){
                    mMediaPlayer.seekTo(progress * 1000);
                }
            }
    });

et ça devrait faire l'affaire! :)

EDIT: Une chose que j'ai remarquée dans votre code, ne faites pas:

public MainActivity() {
    mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
    mFileName += "/audiorecordtest.3gp";
}

faire toutes les initialisations dans votre onCreate(); , ne créez pas de constructeurs de votre Activity .

117
répondu hardartcore 2018-09-07 08:58:49

j'ai utilisé ce tutoriel avec succès, c'est vraiment simple à comprendre: www.androidhive.info/2012/03/android-building-audio-player-tutorial /

C'est la partie intéressante:

/**
 * Update timer on seekbar
 * */
public void updateProgressBar() {
    mHandler.postDelayed(mUpdateTimeTask, 100);
}  

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

           // Displaying Total Duration time
           songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));
           // Displaying time completed playing
           songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));

           // Updating progress bar
           int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration));
           //Log.d("Progress", ""+progress);
           songProgressBar.setProgress(progress);

           // Running this thread after 100 milliseconds
           mHandler.postDelayed(this, 100);
       }
    };

/**
 *
 * */
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

}

/**
 * When user starts moving the progress handler
 * */
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
    // remove message Handler from updating progress bar
    mHandler.removeCallbacks(mUpdateTimeTask);
}

/**
 * When user stops moving the progress hanlder
 * */
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
    mHandler.removeCallbacks(mUpdateTimeTask);
    int totalDuration = mp.getDuration();
    int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);

    // forward or backward to certain seconds
    mp.seekTo(currentPosition);

    // update timer progress again
    updateProgressBar();
}
7
répondu Enrichman 2013-06-18 13:53:32

après avoir initialisé vos MediaPlayer et SeekBar , vous pouvez faire ceci:

 Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
        }
    },0,1000);

Ce mises à jour SeekBar chaque seconde(1000ms)

et pour mettre à jour MediaPlayer , si l'utilisateur fait glisser SeekBar , vous devez ajouter OnSeekBarChangeListener à votre SeekBar :

mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            mMediaPlayer.seekTo(i);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

HAPPY CODING!!!

2
répondu M. Doosti Lakhani 2017-09-28 12:54:35

cochez cette case, vous devez donner des arguments en msecs, Ne pas simplement envoyer progress à seekTo(int)

et cochez également cette case getCurrentPostion () et getduration () .

vous pouvez faire quelques calculs, c'est-à-dire:, convertir progress en msec comme msce = (progress/100)*getDuration() puis faire seekTo(msec)

sinon j'ai une idée facile, vous n'avez pas besoin de modifier le code n'importe qui d'autre n'a qu'à ajouter seekBar.setMax(mPlayer.getDuration()) une fois que votre lecteur multimédia est prêt.

et voici lien exactement ce que vous voulez mise à jour de la barre de recherche

1
répondu Charan Pai 2017-05-23 12:10:32
    int  pos  = 0;
    yourSeekBar.setMax(mPlayer.getDuration());

après avoir commencé votre MediaPlayer I. e mplayer.start()

essayez ce code

while(mPlayer!=null){
         try {
                Thread.sleep(1000);
                pos  = mPlayer.getCurrentPosition();
            }  catch (Exception e) {
                //show exception in LogCat
            }
            yourSeekBar.setProgress(pos);

   }

avant d'ajouter ce code, vous devez créer xml ressource pour SeekBar et l'utiliser dans votre méthode Activity classe d'ur onCreate() .

1
répondu Sam 2013-06-18 13:05:43

pour ajouter à la réponse de @hardartcore.

  1. au lieu d'appeler postDelayed sur un Handler, la meilleure approche serait d'obtenir des callbacks à partir du MediaPlayer pendant play-back et puis en conséquence mettre à jour la seekBar avec le progrès.

  2. mettez aussi en pause votre MediaPlayer à onStartTrackingTouch(SeekBar seekBar) du OnSeekBarChangeListener et redémarrez ensuite sur onStopTrackingTouch(SeekBar seekBar) .

0
répondu Ankit Aggarwal 2016-09-26 10:21:21

basé sur les déclarations précédentes, pour une meilleure performance, vous pouvez également ajouter une condition if

if (player.isPlaying() {
    handler.postDelayed(..., 1000);
}
0
répondu Adrian Grygutis 2017-01-03 09:06:12

le code ci-dessous a fonctionné pour moi.

j'ai créé une méthode pour seekbar

@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    mp.start();
     getDurationTimer();
    getSeekBarStatus();


}
//Creating duration time method
public void getDurationTimer(){
    final long minutes=(mSongDuration/1000)/60;
    final int seconds= (int) ((mSongDuration/1000)%60);
    SongMaxLength.setText(minutes+ ":"+seconds);


}



 //creating a method for seekBar progress
public void getSeekBarStatus(){

    new Thread(new Runnable() {

        @Override
        public void run() {
            // mp is your MediaPlayer
            // progress is your ProgressBar

            int currentPosition = 0;
            int total = mp.getDuration();
            seekBar.setMax(total);
            while (mp != null && currentPosition < total) {
                try {
                    Thread.sleep(1000);
                    currentPosition = mp.getCurrentPosition();
                } catch (InterruptedException e) {
                    return;
                }
                seekBar.setProgress(currentPosition);

            }
        }
    }).start();





    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        int progress=0;

        @Override
        public void onProgressChanged(final SeekBar seekBar, int ProgressValue, boolean fromUser) {
            if (fromUser) {
                mp.seekTo(ProgressValue);//if user drags the seekbar, it gets the position and updates in textView.
            }
            final long mMinutes=(ProgressValue/1000)/60;//converting into minutes
            final int mSeconds=((ProgressValue/1000)%60);//converting into seconds
            SongProgress.setText(mMinutes+":"+mSeconds);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
}

SongProgress et SongMaxLength sont le TextView qui montre la durée et la longueur des chansons.

0
répondu Gopalakrishna Umapathi 2017-02-15 06:01:53

ça marche pour moi:

seekbarPlayer.setMax(mp.getDuration());
getActivity().runOnUiThread(new Runnable() {

    @Override
    public void run() {
        if(mp != null){
            seekbarPlayer.setProgress(mp.getCurrentPosition());
        }
        mHandler.postDelayed(this, 1000);
    }
});
0
répondu Rajesh Gauswami 2017-04-11 02:35:54

essayez ce Code:

public class MainActivity extends AppCompatActivity {

MediaPlayer mplayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

            //You create MediaPlayer variable ==> set the path and start the audio.

    mplayer = MediaPlayer.create(this, R.raw.example);
    mplayer.start();

            //Find the seek bar by Id (which you have to create in layout)
            // Set seekBar max with length of audio
           // You need a Timer variable to set progress with position of audio

    final SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);
    seekBar.setMax(mplayer.getDuration());

    new Timer().scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    seekBar.setProgress(mplayer.getCurrentPosition());
                }
            }, 0, 1000);


            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            // Update the progress depending on seek bar
                    mplayer.seekTo(progress);

                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
        }
0
répondu NEC 2018-06-03 16:25:03

Code en Kotlin:

var updateSongTime = object : Runnable {
            override fun run() {
                val getCurrent = mediaPlayer?.currentPosition
                startTimeText?.setText(String.format("%d:%d",
                        TimeUnit.MILLISECONDS.toMinutes(getCurrent?.toLong() as Long),
                        TimeUnit.MILLISECONDS.toSeconds(getCurrent?.toLong()) -
                                TimeUnit.MINUTES.toSeconds(
                                        TimeUnit.MILLISECONDS.toMinutes(getCurrent?.toLong()))))
                seekBar?.setProgress(getCurrent?.toInt() as Int)
                Handler().postDelayed(this, 1000)
            }
        }

pour changer le lecteur de médias fichier audio chaque seconde

si l'utilisateur traîne la barre de recherche puis l'extrait de code suivant peut être utilisé

Statified.seekBar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
                if(b && Statified.mediaPlayer != null){
                    Statified.mediaPlayer?.seekTo(i)
                }

            }
            override fun onStartTrackingTouch(seekBar: SeekBar) {}
            override fun onStopTrackingTouch(seekBar: SeekBar) {}
        })
0
répondu Bilal H. Hungund 2018-06-22 21:36:03