I am creating a simple app which can play music from a url. There is no forward or backward button.. Just play and the music will stream from url and will be played..
I need that control in notification when i click play button where in notification a close button also should be show to stop the music and clear the notification.
How could i implement it..
my Code in Music is
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
buttonPlayPause.setImageResource(R.drawable.button_pause);
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(audioUrl); // setup song from https://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
Related
Collecting the total duration of an audio has become a problem for me. I am creating an activity that plays an audio from online, I use the android media player. Now the audio is able to play correctly, but the problem I am facing is allowing the seek bar progress accordingly with the audio. The seek bar is set correctly but i have seen that the getDuration returns 0 value.
Below is what i have done.
public class AudioDetails extends AppCompatActivity
implements MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audios_details_activity);
// Mediaplayer
mp = new MediaPlayer();
utils = new AudioUtilities();
// Listeners
songProgressBar.setOnSeekBarChangeListener(this); // Important
mp.setOnCompletionListener(this); // Important
// By default play first song
playSong(0);
/**
* Play button click event
* plays a song and changes button to pause image
* pauses a song and changes button to play image
* */
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// check for already playing
if(mp.isPlaying()){
if(mp!=null){
mp.pause();
// Changing button image to play button
btnPlay.setImageResource(R.drawable.btn_play);
}
}else{
// Resume song
if(mp!=null){
mp.start();
// Changing button image to pause button
btnPlay.setImageResource(R.drawable.btn_pause);
}
}
}
});
}
/**
* Function to play a song
* #param songIndex - index of song
* */
public void playSong(int songIndex){
// Play song
try {
mp.reset();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource("http://test.com/test/upload/Twale_FLO.mp3");
mp.prepareAsync();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
totalDuration =mp.getDuration();
}
});
} catch (IOException e) {
e.printStackTrace();
}
// set Progress bar values
songProgressBar.setProgress(0);
songProgressBar.setMax(99);
// Updating progress bar
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Update timer on seekbar
* */
public void updateProgressBar() {
mHandler.postDelayed(mUpdateTimeTask, 100);
}
/**
* Background Runnable thread
* */
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
long currentDuration = mp.getCurrentPosition();
long totalDuration = mp.getDuration();
// 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();
}
/**
* On Song Playing completed
* if repeat is ON play same song again
* if shuffle is ON play random song
* */
#Override
public void onCompletion(MediaPlayer arg0) {
// check for repeat is ON or OFF
if(isRepeat){
// repeat is on play same song again
playSong(currentSongIndex);
} else{
// play first song
playSong(0);
currentSongIndex = 0;
}
}
#Override
public void onDestroy(){
super.onDestroy();
mp.release();
}}
Please how can I get the total duration of the audio file streaming from online via android? Thanks in advance.
There are some problem with this topic.
The getDuration() does not work on all API versions. So, it is not sure when it will work and when not.
The other way around is to extract metadata. Unfortunately, android MediaMetadataRetriever doesn't work with online source. It works only with sd card files.
Fortunately there is a library available that can help us. And i got the duration with that library. So, these are steps.
add compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.3' to your gradle.build in dependency
Then you can get duration by below code
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource("http://owatechinnovations.com/test/upload/Twale_FLO.mp3");
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
long duration =Long.parseLong(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
duration=duration/1000;
long minute=duration/(60);
long second=duration-(minute*60);
mmr.release();
your_text_view.setText(minute+":"+second);
I get the result "4:18" 4 mins 18 secs. hope it helps you
I have a list of players (ListView). Each item is have two buttons "start" and "stop". When I click on "start" color "Start" button change red and begins to move seekbar. When click on the "stop" button color "start" start is black and seekbar progress becomes zero. when the song ends with the color button "start" also becomes black and seekbar progress becomes zero.
holder.start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
releaseMP();
startPlayProgressUpdater(holder.seekBar, holder.start);
try {
mediaPlayer = new MediaPlayer();
global_position = position;
mediaPlayer.setDataSource(recordBeans.get(global_position).getFile());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
holder.seekBar.setMax(mediaPlayer.getDuration());
mediaPlayer.start();
recordBeans.get(global_position).setPlay(true);
holder.start.setTextColor(Color.RED);
startPlayProgressUpdater(holder.seekBar, holder.start);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
releaseMP();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
This is implemented in this method:
public void startPlayProgressUpdater(final SeekBar seekBar, final Button start) {
if (mediaPlayer != null) {
recordBeans.get(global_position).setSeekPos(mediaPlayer.getCurrentPosition());
if ((Integer) seekBar.getTag() == global_position) {
seekBar.setProgress(recordBeans.get(global_position).getSeekPos());
}
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater(seekBar, start);
}
};
handler.postDelayed(notification, 1000);
} else {
recordBeans.get(global_position).setPlay(false);
start.setTextColor(Color.BLACK);
recordBeans.get(global_position).setSeekPos(0);
seekBar.setProgress(0);
}
}
When I click the "stop" or the song ends, the player becomes the NULL and color button again changes. it is implemented in all of these methods:
holder.stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ((Integer) v.getTag() == global_position && mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
});
and
private void releaseMP() {
if (mediaPlayer != null) {
try {
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want the same functionality if I worked while playing the song click on the "start" another song. ie a new song starts playing, the color buttons "start" becomes A red color and previous button "start" again black.
for this I when you click on "start" call methods:
releaseMP();
startPlayProgressUpdater(holder.seekBar, holder.start);
and the method works but the data is not cleared. but if I click on "Stop" then the data of all previous songs cleared. what I'm doing wrong?
I think you meant to call reset(), not release() in the stop button OnClick. Try to call release() in your main container OnStop()
reset()
This method resets the media player
release()
This method releases any resource attached with MediaPlayer object
I am working on audio streaming android application in this I get song url from server which i am playing using audio streaming application in this when I start playing it starts and it shows buffering also but my problem is when i move seekbar to particular position which is not buffered seekbar handle is moving back.actually I need to start playing song from that position.
see my code and please tell me how to handle this scenario
public class StreamingMp3Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public EditText editTextSongURL;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song duration in milliseconds. Look at getDuration() method in MediaPlayer class
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
editTextSongURL = (EditText)findViewById(R.id.EditTextSongURL);
editTextSongURL.setText("http://instilltech.netii.net/01LECHIPODAMA.mp3");
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(editTextSongURL.getText().toString()); // setup song from http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
}
My ProgressBar does not reset after audio is done. I ask a question before on this and got it working but now just stopped working and not sure why it doesn't. Any help would be awesome.
All I want is it to chose a audio at random then play one and when finished you can press play again to listen to the same audio it chose at random.
Heres code:
public class player1 extends Activity implements Runnable {
private MediaPlayer mp;
private ProgressBar progressBar;
private ImageButton pauseicon;
private final int NUM_SOUND_FILES = 3; //*****REPLACE THIS WITH THE ACTUAL NUMBER OF SOUND FILES YOU HAVE*****
private int mfile[] = new int[NUM_SOUND_FILES];
private Random rnd = new Random();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_1);
pauseicon = (ImageButton) findViewById(R.id.pauseicon);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
getActionBar().setDisplayHomeAsUpEnabled(true);
mfile[0] = R.raw.sound01; //****REPLACE THESE WITH THE PROPER NAMES OF YOUR SOUND FILES
mfile[1] = R.raw.sound02; //PLACE THE SOUND FILES IN THE /res/raw/ FOLDER IN YOUR PROJECT*****
mfile[2] = R.raw.sound03;
/**
* Play button click event
* plays a song and changes button to pause image
* pauses a song and changes button to play image
* */
try{
mp = MediaPlayer.create(player1.this, mfile[rnd.nextInt(NUM_SOUND_FILES)]);
mp.seekTo(0);
mp.start(); ;
progressBar.setVisibility(ProgressBar.VISIBLE);
progressBar.setProgress(0);
progressBar.setMax(mp.getDuration());
new Thread(this).start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
mp.setOnCompletionListener(new OnCompletionListener() {
//When audio is done will change pause to play
public void onCompletion(MediaPlayer mp) {
pauseicon.setImageResource(R.drawable.playicon);
}
});
pauseicon.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// No need to check if it is pauseicon
if(mp.isPlaying()){
mp.pause();
((ImageButton) v).setImageResource(R.drawable.playicon);
} else {
mp.start();
((ImageButton) v).setImageResource(R.drawable.pauseicon);
}}});
}
//To update progress bar
public void run() {
int currentPosition= 0;
int total = mp.getDuration();
while (mp!=null && currentPosition<=total) {
try {
Thread.sleep(1000);
currentPosition= mp.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
progressBar.setProgress(currentPosition);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
if (mp != null)
if(mp.isPlaying())
mp.stop();
mp.release();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed(){
if (mp != null){
if(mp.isPlaying())
mp.stop();
mp.release();
}
//there is no reason to call super.finish(); here
//call super.onBackPressed(); and it will finish that activity for you
super.onBackPressed();
}
}
You problem is mp.getDuration() is a milliseconds, which changes in each song. So don't use progressBar.setMax(mp.getDuration());. As it only works once for the very first song. Use progressBar.setMax(100); instead. Then use currentPosition= 100 * mp.getCurrentPosition() / mp.getDuration(); This should work fine.
Also don't forget adding progressBar.setProgress(0); when one song is finished or stop-button is clicked.
EDIT: Try resetting it inside of your completion listener. Scratch the setter then. Try using this:
Thread.sleep(1000);
currentPosition++;
Instead of this:
Thread.sleep(1000);
currentPosition= mp.getCurrentPosition();
That is in your run() function. Then it will increment from 0 to total and you won't have to worry about getting or setting the currentposition, just the progress which is being done with the previous change below.
mp.setOnCompletionListener(new OnCompletionListener() {
//When audio is done will change pause to play
public void onCompletion(MediaPlayer mp) {
pauseicon.setImageResource(R.drawable.playicon);
//Reset here
progressBar.setProgress(0);
}
});
I tried various approaches but nothing is solving my problem. Hope someone here can help me.
Simple requirement is I want to show a spinner until media player window is shown. It sounds easy enough but it is not.
I am calling my mediaplayer class on "Listen" click of alertDialog. Here it is:
alertBox.setCancelable(false)
.setNegativeButton("Listen", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int id){
dialog.dismiss();
emp = new EasyMediaPlayer(mp3PopupLayout,buttonPlayPause,seekBarProgress,tv_mp3,downloadURL);
emp.startPlayingMP3();
}
}).show();
And startPlaying function calls chooseToStart(true) which in-turn runs the media player. This class is:
public class EasyMediaPlayer implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
EasyMediaPlayer(View mp3PopupLayout,ImageView buttonPlayPause,SeekBar seekBarProgress,TextView tv_mp3, String MP3URL){
this.mp3PopupLayout = mp3PopupLayout;
this.buttonPlayPause = buttonPlayPause;
this.seekBarProgress = seekBarProgress;
this.tv_mp3 = tv_mp3;
this.MP3URL = MP3URL;
seekBarProgress.setOnTouchListener(this);
buttonPlayPause.setOnClickListener(this);
}
public void startPlayingMP3(){
mediaFileLengthInMilliseconds = 1;
tv_mp3.setText("");
buttonPlayPause.setImageResource(R.drawable.button_play);
buttonPlayPause.setVisibility(View.GONE);
seekBarProgress.setProgress(0);
seekBarProgress.setSecondaryProgress(0);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
tv_mp3.setText("Error in playing file !!");
return true;
}
});
mp3DownloadWindow = new PopupWindow(mp3PopupLayout, LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, true);
mp3DownloadWindow.showAtLocation(mp3PopupLayout, Gravity.BOTTOM, 30, 0);
chooseToStart(true);
}
public void chooseToStart(boolean startFlag){
if(startFlag){
try {
mediaPlayer.setDataSource(this.MP3URL);
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
} catch (Exception e) {
tv_mp3.setText(e.toString() + "\nClose it");
}
if(!mediaPlayer.isPlaying()){
spinner.cancel();
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
//other stuff
}
I need to know where and how I can use spinner so it will be shown until media player starts playing.
Any help will be appreciated. Thanks
Use prepareAsync() and setOnPreparedListener() instead of prepare().
mediaPlayer.setDataSource(this.MP3URL);
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// Hide whatever you need, mediaPlayer is prepared
mp.start();
}
});
// Show whatever you need, mediaPlayer is preparing
mediaPlayer.prepareAsync();