SeekBar and media player in android - android

I have a simple player and recorder. Everything works great but have one problem. I want to add seek bar to see progress in playing record and use this seek bar to set the place from the player should play. I have onProgress but with no effect. This is the 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
}
}
Any ideas on how to use seek bar to see progress and set place from the record should play?

To create a 'connection' between SeekBar and MediaPlayer you need first to get your current recording max duration and set it to your seek bar.
mSeekBar.setMax(mFileDuration/1000); // where mFileDuration is mMediaPlayer.getDuration();
After you initialise your MediaPlayer and for example press play button, you should create handler and post runnable so you can update your SeekBar (in the UI thread itself) with the current position of your MediaPlayer like this :
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);
}
});
and update that value every second.
If you need to update the MediaPlayer's position while user drag your SeekBar you should add OnSeekBarChangeListener to your SeekBar and do it there :
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);
}
}
});
And that should do the trick! : )
EDIT:
One thing which I've noticed in your code, don't do :
public MainActivity() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}
make all initialisations in your onCreate(); , do not create constructors of your Activity.

I've used this tutorial with success, it's really simple to understand:
www.androidhive.info/2012/03/android-building-audio-player-tutorial/
This is the interesting part:
/**
* 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();
}

After you initialize your MediaPlayer and SeekBar, you can do this :
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
},0,1000);
This updates SeekBar every second(1000ms)
And for updating MediaPlayer, if user drag SeekBar, you must add OnSeekBarChangeListener to your 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!!!

Code in 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)
}
}
For changing media player audio file every second
If user drags the seek bar then following code snippet can be use
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) {}
})

check this, you should give arguments in msecs, Dont just send progress to seekTo(int)
and also check this getCurrentPostion() and getDuration().
You can do some calcuations, ie., convert progress in msec like msce = (progress/100)*getDuration() then do seekTo(msec)
Or else i have an easy idea, you don't need to change any code anywer else just add seekBar.setMax(mPlayer.getDuration()) once your media player is prepared.
and here is link exactly what you want seek bar update

The below code worked for me.
I've created a method for 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 and SongMaxLength are the TextView to show song duration and song length.

My code snippet:
public class PlayerActivity extends AppCompatActivity {
private static final String TAG = "PlayerActivity";
private ActivityPlayerBinding binding;
private MediaPlayer mediaPlayer;
private boolean playingAudio = false;
Runnable runnable;
Handler handler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityPlayerBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mediaPlayer.setDataSource(songUrl);
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(mp -> {
binding.playBtn.setBackground(getDrawable(R.drawable.ic_pause));
binding.seekbarPlayer.setMax(mp.getDuration());
mediaPlayer.start();
playingAudio = true;
updateSeekbar();
});
mediaPlayer.setOnBufferingUpdateListener((mp, percent) -> {
double ratio = percent / 100.0;
int bufferingLevel = (int) (mp.getDuration() * ratio);
binding.seekbarPlayer.setSecondaryProgress(bufferingLevel);
});
binding.seekbarPlayer.setOnSeekBarChangeListener(seekBarChangeListener);
}
private SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
seekBar.setProgress(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
};
private void updateSeekbar() {
try {
if (mediaPlayer != null) {
int currentPos = mediaPlayer.getCurrentPosition();
binding.seekbarPlayer.setProgress(currentPos);
runnable = this::updateSeekbar;
handler.postDelayed(runnable, 1000);
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "updateSeekbar: " + e.getMessage());
}
}
}

int pos = 0;
yourSeekBar.setMax(mPlayer.getDuration());
After You start Your MediaPlayer i.e mplayer.start()
Try this code
while(mPlayer!=null){
try {
Thread.sleep(1000);
pos = mPlayer.getCurrentPosition();
} catch (Exception e) {
//show exception in LogCat
}
yourSeekBar.setProgress(pos);
}
Before you added this code you have to create xml resource for SeekBar and use it in Your Activity class of ur onCreate() method.

This works for me:
seekbarPlayer.setMax(mp.getDuration());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if(mp != null){
seekbarPlayer.setProgress(mp.getCurrentPosition());
}
mHandler.postDelayed(this, 1000);
}
});

Given the answer hardartcore that worked for me with a small change and did not work before the change:
private Handler mHandler = new Handler();
MusicPlayer.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(player != null){
int mCurrentPosition = player.getCurrentPosition();//clear ' /1000 '
seekBar.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
seekBar.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(player != null && fromUser){
player.seekTo(progress); // clear ' * 1000 '
}
}
});

To add on to #hardartcore's answer.
Instead of calling postDelayed on a Handler, the best approach would be to get callbacks from the MediaPlayer during play-back and then accordingly update the seekBar with the progress.
Also, pause your MediaPlayer at onStartTrackingTouch(SeekBar seekBar) of the OnSeekBarChangeListener and then re-start it on onStopTrackingTouch(SeekBar seekBar).

Based on previous statements, for better performance, you can also add an if condition
if (player.isPlaying() {
handler.postDelayed(..., 1000);
}

Try this 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) {
}
});
}

Related

Android audio player not play like whatsApp audio player

when i am play audio player and between playing i am play second audio first audio progress bar and timer sink with second audio player and so on . please help on this .**All audio are loaded in recyclerview.**I want audio Player like whatsapp play audio one by one and there progress bar no sink with each other
if (message.getFileType() == MessageFileType.AUDIO)
{
mediaUrl=message.getFile();
Log.d("tag","mediaURL"+mediaUrl);
Uri video = Uri.parse(mediaUrl);
holder.BtnPlayMusic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.BtnPlayMusic.setImageResource(R.drawable.pause_button_red);
if(flag){
mPlayer = MediaPlayer.create(mContext, video);
flag = false;
}
if ( mPlayer.isPlaying())
{
holder.MusicSeekBar.setProgress(0);
mPlayer.stop();
flag=true;
// mPlayer.reset();
holder.BtnPlayMusic.setImageResource(R.drawable.play_button_red);
mPlayer = MediaPlayer.create(mContext, video);
flag = false;
mPlayer.start();
holder.BtnPlayMusic.setImageResource(R.drawable.pause_button_red);
getDurationTimer(holder);
holder.MusicSeekBar.setMax(mPlayer.getDuration()/1000);
getSeekBarStatus(holder);
}
else
{
mPlayer.start();
getDurationTimer(holder);
holder.BtnPlayMusic.setImageResource(R.drawable.pause_button_red);
holder.MusicSeekBar.setMax(mPlayer.getDuration()/1000);
getSeekBarStatus(holder);
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
holder.BtnPlayMusic.setImageResource(R.drawable.play_button_red);
flag=true;
holder.MusicSeekBar.setProgress(0);
}}); }}
});
holder.BtnStopMusic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPlayer.stop();
mPlayer.reset();
flag=true;
// mPlayer.reset();
holder.BtnPlayMusic.setImageResource(R.drawable.play_button_red);
}
});
}
//Creating duration time method
public void getDurationTimer(MessageViewHolder holder){
final long minutes=(mPlayer.getDuration()/1000)/60;
final int seconds= (int) ((mPlayer.getDuration()/1000)%60);
holder.MusicTime.setText(minutes+ "0:0"+seconds);
}
//creating a method for seekBar progress
public void getSeekBarStatus(MessageViewHolder holder){
thread=new Thread(new Runnable() {
#Override
public void run() {
int currentPosition = 0;
int total = mPlayer.getDuration();
holder.MusicSeekBar.setMax(total);
while (mPlayer != null && currentPosition < total && flag==false) {
try {
Thread.sleep(1000);
currentPosition = mPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
}
holder.MusicSeekBar.setProgress(currentPosition);
}
}
});
thread.start();
holder.MusicSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int progress=0;
#Override
public void onProgressChanged(final SeekBar seekBar, int ProgressValue, boolean fromUser) {
if (fromUser) {
mPlayer.seekTo(ProgressValue);//if user drags the seekbar, it gets the position and updates in textView.
progress=ProgressValue;
}
final long mMinutes=(ProgressValue/1000)/60;//converting into minutes
final int mSeconds=((ProgressValue/1000)%60);//converting into seconds
holder.MusicTime.setText(mMinutes+"0:0"+mSeconds);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mPlayer.seekTo(progress);
}
});
}

SeekBar is not updating music is playing but the seekBar stay idle

I am playing mp3 file from url, but SeekBar is not updating while playing song.
It showing a buffering but not moving automatically when song starts.
When i am trying to move forcefully then also it working fine.
Below code i am using to play and update SeekBar.
I wanted to create a seekBar that track the progress of a mediaplayer but it doesnt work out quite well, the music is playing but the seekbar stay idle. Is there something that I left out?
Please help me i am new in android.
public class XYZ extends Fragment implements MediaPlayer.OnBufferingUpdateListener,MediaPlayer.OnCompletionListener{
private SeekBar seekBar;
private MediaPlayer mediaPlayer;
private int mediaFileLength;
final Handler handler = new Handler();
private int realtimeLength;
Button b,b3,b4;
private double startTime = 0;
private double finalTime = 0;
public static int oneTimeOnly = 0;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_outside, container,
false);
rootView.setBackgroundResource(R.drawable.jotirling);
seekBar = rootView.findViewById(R.id.seekbar);
seekBar.setMax(99); // 100% (0~99)
seekBar.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (mediaPlayer.isPlaying()) {
SeekBar seekBar = (SeekBar) v;
int playPosition = (mediaFileLength / 100) * seekBar.getProgress();
mediaPlayer.seekTo(playPosition);
}
return false;
}
});
b3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog mDialog = new ProgressDialog(getActivity());
#SuppressLint("StaticFieldLeak") AsyncTask<String, String, String> mp3Play = new AsyncTask<String, String, String>() {
#Override
protected void onPreExecute() {
mDialog.setMessage("Please wait It will take time according to your network speed...!");
mDialog.show();
mDialog.setCancelable(false);
}
#Override
protected String doInBackground(String... params) {
try {
mediaPlayer.setDataSource(params[0]);
mediaPlayer.prepare();
} catch (Exception ignored) {
}
return "";
}
#Override
protected void onPostExecute(String s) {
mediaFileLength = mediaPlayer.getDuration();
realtimeLength = mediaFileLength;
if (!mediaPlayer.isPlaying()) {
p=1;
mediaPlayer.start();
Toast.makeText(getActivity(), "Playing sound", Toast.LENGTH_SHORT).show();
finalTime = mediaPlayer.getDuration();
startTime = mediaPlayer.getCurrentPosition();
b3.setBackgroundResource(R.drawable.pp);
if (oneTimeOnly == 0) {
oneTimeOnly = 1;
}
} else {
p=0;
mediaPlayer.pause();
Toast.makeText(getActivity(), "Pausing "+
"sound",Toast.LENGTH_SHORT).show();
b3.setBackgroundResource(R.drawable.p);
}
updateSeekBar();
mDialog.dismiss();
}
};
mp3Play.execute("URL"); // direct link mp3 file
}
});
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
return rootView;
}
private void updateSeekBar() {
seekBar.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaFileLength) * 100));
if (mediaPlayer.isPlaying()) {
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
}
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
seekBar.setSecondaryProgress(percent);
}
}
You should consider using setOnSeekbarChangeListener()
Reference : setOnSeekBarChangeListener()
Simple example would be
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
// TODO Auto-generated method stub
if(fromUser){
//do your things, like updating time durations etc.
}
}
});
Also if u a want working example, look at this link for code (i have just used circularSeekbar instead of regular one) https://github.com/iamSahdeep/Bop/blob/master/app/src/main/java/com/sahdeepsingh/Bop/Activities/PlayerView.java#L324
More Examples : https://www.javatips.net/api/android.widget.seekbar.onseekbarchangelistener
You can create use Timer for this:
seekBar.setMax(mediaPlayer.getDuration());
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
},0,1000);
You are defining Runnable updater but not calling it.
if (mediaPlayer.isPlaying()) {
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
}
};
seekBar.post(updater)
}

How to use seekbar on a streaming media player?

I am working on an online radio app and I tried implementing a seek bar to it like the tunein. I gave the seekbar a max value since i could not use the MediaPlayer's .getDuration() method.
I successfully implemented it but when I try moving the seekbar it goes back to its previous position and somehow my play/pause button stops working.
HERE IS THE SUMMARISED CODE
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
handler = new Handler(); //for seekbar
seekBar = (SeekBar) findViewById(R.id.seekBar);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(radioLink);
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (started) {
started = false;
mediaPlayer.pause();
playButton.setImageResource(R.drawable.pplay);
} else {
started = true;
mediaPlayer.start();
playButton.setImageResource(R.drawable.ppause);
}
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b)
{
mediaPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
loadingSoundtxt.setVisibility(View.GONE);
playButton.setVisibility(View.VISIBLE);
seekBar.setMax(1800000); //30mins in milliseconds
mediaPlayer.start();
changeSeekbar();
}
}
private void changeSeekbar(){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
if (mediaPlayer.isPlaying())
{
runnable = new Runnable() {
#Override
public void run() {
changeSeekbar();
}
};
handler.postDelayed(runnable, 1000);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) mediaPlayer.release();
}
}

Why isn't the seekbar moving as youtube video is playing in android?

I've implemented a youtube player (fragment) in my android project. I'm tryin' to play the video in chromeless player style, while implementing player control on my own. Play and pause buttons are working fine, however seekbar isn't moving as the video is progressing. Though, I'm able to skip video through it (play video ahead), but the seekbar isn't moving on it's own. Where did I go wrong?
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
if (!b) {
YPlayer = youTubePlayer;
displayCurrentTime(); // It displays current progress of video in --:-- format. It's working fine...
YPlayer.loadVideo(id); // id -> YouTube video id
YPlayer.play();
YPlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
YPlayer.setPlayerStateChangeListener(new YouTubePlayer.PlayerStateChangeListener() {
#Override
public void onLoading() {
}
#Override
public void onLoaded(String s) {
}
#Override
public void onAdStarted() {
}
#Override
public void onVideoStarted() {
seekBar.setMax(YPlayer.getDurationMillis()/1000);
}
#Override
public void onVideoEnded() {
}
#Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
}
});
YPlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
#Override
public void onPlaying() {
handler.postDelayed(runnable, 100); //Handler's instance initialized as instance variable
displayCurrentTime();
}
#Override
public void onPaused() {
handler.removeCallbacks(runnable);
}
#Override
public void onStopped() {
}
#Override
public void onBuffering(boolean b) {
handler.postDelayed(runnable, 1000);
}
#Override
public void onSeekTo(int i) {
handler.removeCallbacks(runnable);
}
});
playerControl.setVisibility(View.VISIBLE); //Layout with play (and pause) button, Seekbar (which isn't moving along with the video), and timer (string being returned by the above displayCurrentTime() method)
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
long lengthPlayed = (YPlayer.getDurationMillis() * progress) / 100;
YPlayer.seekToMillis((int) lengthPlayed);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
runOnUiThread(new Runnable() {
#Override
public void run() {
while(YPlayer != null && seekBar.getMax() > YPlayer.getCurrentTimeMillis())
{
int videoProgressed = 0;
try
{
Thread.sleep(1000);
videoProgressed = YPlayer.getCurrentTimeMillis();
}
catch (Exception e)
{
e.printStackTrace();
}
seekBar.setProgress(videoProgressed);
}
}
});
private void displayCurrentTime() {
if (YPlayer != null) {
String formattedTime = formatTime(YPlayer.getCurrentTimeMillis());
playTime.setText(formattedTime);
}
}
private String formatTime(int millis) {
int seconds = millis / 1000;
int minutes = seconds / 60;
return String.format("%02d:%02d", minutes % 60, seconds % 60);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
if(YPlayer != null) {
displayCurrentTime();
}
handler.postDelayed(this, 1000);
}
};
USE THIS CODE
Custom youtube player CHROMELESS style - set SeekBar Progress and Seek Bar TrackingTouch Forward/backward,
mSeekBar = (SeekBar) findViewById(R.id.video_seekbar);
mSeekBar.setOnSeekBarChangeListener(mVideoSeekBarChangeListener)
SeekBar.OnSeekBarChangeListener mVideoSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
long lengthPlayed = (mYouTubePlayer.getDurationMillis() * seekBar.getProgress()) / 100;
mYouTubePlayer.seekToMillis((int) lengthPlayed);
}
};
private Runnable runnable = new Runnable() {
#Override
public void run(){
displayCurrentTime();
mHandler.postDelayed(this, 100);
}
};
private void displayCurrentTime() {
if (null == mYouTubePlayer) return;
String formattedTime = formatTime(mYouTubePlayer.getDurationMillis() - mYouTubePlayer.getCurrentTimeMillis());
play_timetv.setText(formattedTime);
playPercent = (int) (((float) mYouTubePlayer.getCurrentTimeMillis()/(float) mYouTubePlayer.getDurationMillis()) * 100);
System.out.println("get youtube displayTime 2 : "+playPercent);
// update live progress
mSeekBar.setProgress(playPercent, true);
}
Check this tutorial if it can help you. This tutorial is all about Android Building Audio Player. It discuss here on how to build a simple audio player with basic controls like play, pause, forward, backward, next, previous, playlist and seekbar.
Just check the code in where the tutorial explain on how to update progress bar timer implemented in a background thread which runs in background using a Handler. You can check here how the seekbar being implemented.
For more information, check this related SO question.
Add youtubeSeekBar.setProgress(yPlayer.getCurrentTimeMillis()/100); in on playing() event
YPlayer.setPlaybackEventListener(new YouTubePlayer.PlaybackEventListener() {
#Override
public void onPlaying() {
handler.postDelayed(runnable, 100); //Handler's instance initialized as instance variable
displayCurrentTime();
youtubeSeekBar.setProgress(yPlayer.getCurrentTimeMillis()/100); //this is your key of success
}
#Override
public void onPaused() {
handler.removeCallbacks(runnable);
}
#Override
public void onStopped() {
}
#Override
public void onBuffering(boolean b) {
handler.postDelayed(runnable, 1000);
}
#Override
public void onSeekTo(int i) {
handler.removeCallbacks(runnable);
}
});
playerControl.setVisibility(View.VISIBLE); //Layout with play (and pause) button, Seekbar (which isn't moving along with the video), and timer (string being returned by the above displayCurrentTime() method)
}

Music Player Seekbar using Android Studio

I was working in a very simple music player with a seek bar.
I could make it working but I got a problem with playing music, it doesn't work correctly every second - it backwards a while, then remain again like it's a buggy.
Here's full code:
private MediaPlayer mediaPlayer;
private Button button;
private TextView textView;
private SeekBar seek;
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
textView = (TextView)findViewById(R.id.text);
seek = (SeekBar)findViewById(R.id.seek);
mediaPlayer = new MediaPlayer();
mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.threedays);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if(mediaPlayer != null){
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
seek.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
seekBar.setMax(mediaPlayer.getDuration() / 1000);
textView.setText(progress + "/" + seekBar.getMax());
mediaPlayer.seekTo(progress*1000);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
pause();
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
pause();
} else {
start();
}
}
});
}
public void start(){
if(mediaPlayer!=null) {
mediaPlayer.start();
button.setText("Pause");
}
}
public void pause(){
if(mediaPlayer!=null) {
mediaPlayer.pause();
button.setText("Play");
}
}
#Override
protected void onDestroy() {
if(mediaPlayer!=null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mediaPlayer.release();
mediaPlayer = null;
}
super.onDestroy();
}
Try this code on seek.setOnSeekBarChangeListener
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
seekBar.setMax(mediaPlayer.getDuration() / 1000);
textView.setText(progress + "/" + seekBar.getMax());
if(fromUser)
{
mediaPlayer.seekTo(progress*1000);
}
}

Categories

Resources