I am currently using the Glide library to show a gif in my android device, on specific event, but now I also want to set audio as background when the gif is playing, and when it stops the audio also stops!
Attempt:
Glide.with(this).load(R.drawable.somegifFile).into(imageView);
try {
if (mp.isPlaying()) {
mp.stop();
mp.release();
mp = MediaPlayer.create(context, R.raw.sound);
}
mp.start();
} catch(Exception e) { e.printStackTrace(); }
Ok try this
1. First check weather image view is null or it's not loaded with an image
2. If its loaded then it means gif starts working .. then start a timer and make it call after every 10 seconds
3. inside that's run() method refresh the audio like you did
private void startWaitingTimeRunner() {
waitingTimer = new Timer();
waitingTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// reset audio -> stop , release , play gain
}
}, 0, 10000);
}
Related
This question already has answers here:
Media Player start stop start
(8 answers)
Closed 6 years ago.
I have a button when clicked it plays an audio, and while it is playing I can pause it and replay it again and so forth. I have a shake event, where I want to play the audio on shake and replay it when device is shaken again (by first stopping the audio, calling stopAudio?)
I have the following code:
llBtn = (LinearLayout) findViewById(R.id.button);
llBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(MainActivity.this, "LL WAS CLICKED", Toast.LENGTH_SHORT).show();
//IF AUDIO IS NOT PLAYING... PLAY AUDIO
if (tvPS.getText() == "Stop Phrase!") {
StopAudio();
}
else {
PlayAudio();
}
}
});
//the same button is clicked to stop, it is currently setting to Pause.
public void StopAudio() {
mediaPlayer.pause();
Toast.makeText(MainActivity.this, "STOPPED", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
}
public void PlayAudio() {
//stopPlaying(mediaPlayer);
tvPS.setText("Stop Phrase!");
inResId = getResources().getIdentifier("play" , "raw", getPackageName());
mediaPlayer = MediaPlayer.create(getBaseContext(), inResId);
mediaPlayer.seekTo(0);
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
mediaPlayer.pause();
}
});
}
...
public void onShake() {
// Do stuff!
Toast.makeText(getBaseContext(), "Motion detected",
Toast.LENGTH_SHORT).show();
if (mediaPlayer == null) {
PlayAudio();
}
}
How can I modify the code above to handle Play, and then stop if stopped in the middle and then able to replay it again.
The button click works but I am creating a new instance each time and not recycling. When the device is shaken, it plays the audio twice instead of just once.
First of all create the MediaPlayer in onCreate of the context and not in some listener, and don't forget to release it when done, since it consumes a lot of resources,
mediaPlayer.release();
mediaPlayer = null;
Next thing, stop the audio using the stop() function instead of the pause() on completion of the song.
Steps
If you are using a service/activity to play a video create a MediaPlayer instance before it's usage begins, likely in onCreate.
Later use that instance to play/pause/stop the media.
In the onStop of the Service/Activity release the MediaPlayer instance.
Update your playMusic() function to use the MediaPlayer instance you just created, also in the listener use stop() instead of pause()
To change track of an existing MediaPlayer instance
You can use this:
String path = getExternalFilesDir(null).toString()+"/";
mMediaPlayer.setDataSource(path + mediafile);
Link: Changing data source for audio playback using existing MediaPlayer?
for last three weeks I have worked on a Media Player in Android.I am trying to find a solution of how can I make my Media Player to change the song when it's already playing one.
Here is my Listener on the RecyclerView
musicList.addOnItemTouchListener(
new RecyclerItemClickListener(getApplicationContext(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, final int position) {
currentPosition = position;
if(!mediaPlayer.isPlaying()){
musicThread.start();
} else {
mediaPlayer.reset();
}
}
})
);
}
and my Thread is this:
final Thread musicThread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL = getMusicURL(myDataset[currentPosition]);
try {
mediaPlayer.setDataSource(URL);
//mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.prepareAsync(); // prepare async to not block main thread
} catch (IOException e) {
e.printStackTrace();
Log.i("TEST","Eroare: "+e.getMessage());
}
} catch (StorageApiException e) {
e.printStackTrace();
Log.i("TEST","Eroare: "+e.getMessage());
}
}
});
I think you have a mess. First of all, you dont need a thread to play music, the own mediaplayer API does it for you when you call mediaPlayer.start(). However, you have to care about the time it takes to prepare the data source if you are for example streaming online music. For this, just use mediaPlayer.prepareAsync() and register a callback. When it has finished preparing, you can automatically start playing or do whatever you want.
If you want to change the data source, just follow the automaton map that you can find in MediaPlayer docs. Essentially, when the user selects another track, you register the call in your button listener, then reset the mediaPlayer, and recall all prepare, start... cycle again. By the way, it is advised to deploy all your mediaplayer code into a service so that it can keep playing even though the user has closed your activity.
I have set:
mSeekBar.setMax(mp.getDuration()); // 8480
After completion of Audiofile, What I am getting is:
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer)
{
Log.e("onComplete>>", ""+mediaPlayer.getCurrentPosition());
// mediaPlayer.getCurrentPosition() = 8192
Log.e("getDuration", ""+mediaPlayer.getDuration());
// mediaPlayer.getDuration() = 8480
if(mediaPlayer.getCurrentPosition()>=mediaPlayer.getDuration())
{
// Why never get called???
}
}
});
So, Why is MediaPlayer's Current position never reaches the total duration of Audio file ?
Or technically we can say as:
Why Not?
mediaPlayer.getCurrentPosition()==mediaPlayer.getDuration()
Why Always
mediaPlayer.getCurrentPosition() < mediaPlayer.getDuration()
in OnCompletion listener?
For Example:
I have a Play Symbol for starting the Player. Now when I press play symbol it will convert to Pause symbol.
I have a Maxduration of audiodfile.
Now I want to convert Pause symbol to Play Symbol when Audio file is played completely.
SO what I am doing is Checking:
if(mediaPlayer.getCurrentPosition()>=mediaPlayer.getDuration())
{
// Convert Imagview from Pause to Play
// But never get called
}
If you need to do some task on completion by checking currentPoision to duration, you can do below trick:
if(mediaPlayer.getDuration()-mediaPlayer.getCurrentPosition()<1000){//milliseconds
new Handler().postDelayed(
new Runnable() {
#Override
public void run() {
// Convert Imageview from Pause to Play
}
},1000);
}
I have a list of songs that I'm streaming using the MediaPlayer. Some of the songs consistently work and others consistently do not work. I can't see a difference between these files, and they seem to play fine in itunes and such.
When the songs fail it is throwing an IllegalStateException on the mediaPlayer.prepare() line. The IllegalStateException that is thrown has no useful info in it, (detailMessage is null, stackState is null)
Here is my code
try {
mediaPlayer.setDataSource(media.url);
setPlayerState(PlayerState.PREPARING);
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "bad stream");
}
Here is a url to the file that does NOT work:
skdy.bryceb.dev.mediarain.com/song.m4a
Here is one that DOES work:
skdy.bryceb.dev.mediarain.com/song2.m4a
Any ideas why this works on some songs and fails on others?
Thanks MisterSquonk I'm sure that way would work.
In my particular case after beating my head against the wall for a while I realized that on some songs, I was getting to the buffered amount before the player state was getting set to prepared. So I added a check to make sure that the MediaPlayer was in the "PREPARED" state and then it worked great:
// Media prepared listener
mediaPlayer.setOnPreparedListener(
new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
setPlayerState(PlayerState.PREPARED);
}
});
// Media buffer listener
mediaPlayer.setOnBufferingUpdateListener(
new MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// Sometimes the song will finish playing before the 100% loaded in has been
// dispatched, which result in the song playing again, so check to see if the
// song has completed first
if(getPlayerState() == PlayerState.COMPLETED)
return;
if(getPlayerState() == PlayerState.PAUSED)
return;
// If the music isn't already playing, and the buffer has been reached
if(!mediaPlayer.isPlaying() && percent > PERCENT_BUFFER) {
if(getPlayerState() == PlayerState.PREPARED)
{
mediaPlayer.start();
setPlayerState(PlayerState.PLAYING);
}
//if it isn't prepared, then we'll wait till the next buffering
//update
return;
}
}
});
OK, I hacked together a minimal Mediaplayer implementation in a 'sandbox' app/activity I always keep spare for testing.
I might be wrong but if you're streaming these songs over the net, you'll need to prefix the url with http://.
I tried the urls with Winamp and Chrome verbatim (no protocol prefix string) and they worked fine although it's likely both of those applications will use some form of intelligence to work out how to connect/stream.
If I tried that in my mediaPlayer code, I get the same exception as you but if I prefix the urls with http:// the songs play fine.
Example...
// Activity scope
Button button;
CheckBox checkBox;
String url = "";
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//button declared in my activity
button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
if (!checkBox.isChecked())
url = getString(R.string.url_song1);
else
url = getString(R.string.url_song2);
mediaPlayer = new MediaPlayer();
}
#Override
public void onClick(View arg0) {
try {
Log.i(TAG, "onClick() entered...");
mediaPlayer.setDataSource(url);
Log.i(TAG, "Preparing mediaplayer...");
mediaPlayer.prepare();
Log.i(TAG, "Starting mediaplayer...");
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "bad stream");
}
}
If I copy the songs to my SD card both play fine and as long as the internet url strings have an 'http://' prefix then they also work.
I am currently working on an application for Android and I'm using Eclipse and of course Android SDK, but I have bumped in to a problem that is almost the only thing I need to fix before I can relaese a beta-version to Android Market.
So, my problem is that I have an xml with 4 different buttons, and if the user press on a certain button, one sound will be played, and if the user press any of the other buttons is pressed another sound will play but the sound only play sometimes, I want it to play every time the user press a button.
Here's my code(concerning the mediaplayer):
public MediaPlayer right=null;
public MediaPlayer wrong=null;
if(right!=null) {
right.reset();
right.release();
}
if(wrong!=null) {
wrong.reset();
wrong.release();
}
right = MediaPlayer.create(getBaseContext(), R.raw.rightsound);
wrong = MediaPlayer.create(getBaseContext(), R.raw.wrongsound);
if(****()){
right.start();
}
else {
wrong.start();
}
That's my code and I would be very grateful if somebody could help me solve my problem.
new Thread() {
public void run() {
int sound = R.raw.wrongsound;
if(****()) {
sound = R.raw.rightsound;
}
mp = MediaPlayer.create(Test.this, sound);
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.start();
}
}.start();