I'm trying to play a music file, and then a second file which is a second part of the song. The problem is, the transition between the two is very lacking. After one part finishes playing, there's about a second of silence, and then the second part starts playing.
In best case, both files would play seamlessly one after another. I tried using a second MediaPlayer, preparing it beforehand so the only thing left is to start it, but it didn't help. Is there a way to start playing the second part earlier?
Here's the code:
// MediaPlayers are created as "music" and "musicfollow"
//setting up files for source
AssetFileDescriptor anticip = getAssets().openFd("file1.ogg");
AssetFileDescriptor afdass1 = getAssets().openFd("file2.ogg");
//setting a new source for player
music.reset();
try {
music.setDataSource(anticip.getFileDescriptor(), anticip.getStartOffset(),anticip.getLength());
music.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//preparing follow-up music player
musicfollow.reset();
musicfollow.setLooping(true);
try {
musicfollow.setDataSource(afdass1.getFileDescriptor(), afdass1.getStartOffset(),afdass1.getLength());
musicfollow.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//playing part 1
music.start();
//changing the MediaPlayer to follow-up player
music.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
musicfollow.start();
}
});
}
Related
I have an Android app with two media players close to eachother, playing videos. The loop is enabled. When it is running, I notice one of the videos get a bit off from the other for a few hundred ms which is noticeable. The two videos are crops of the same video that's why when the guy moves, it gets clear there is an edge. I was trying to manually add a few milliseconds to the other one using
mp[1].seekTo(mp[0].getCurrentPosition()+700)
but unfortunately it gets off as time passes. And everytime it gets different. I was using Thread and set the mediaPlayer.start() of the two players at the same time (as this post suggested), but that also didn't help. How can I solve the problem? Any thoughts?
mp[0] = mediaPreparation("waldo_short_1.mp4", false);
mp[1] = mediaPreparation("waldo_short_2.mp4", false);
mp[0].start();
mp[1].start();
mp[1].seekTo(mp[0].getCurrentPosition()+705);
MediaPlayer mediaPreparation(String filename, boolean setMute) {
// create mediaplayer instance
MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor afd;
try {
afd = getContext().getAssets().openFd(filename);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.prepare();
} catch (IOException e) {
}
mediaPlayer.setLooping(true);
// mediaPlayer.start();
return mediaPlayer;
}
I have an Android app that contains a String with numbers between 1 and 6 (e.g 165231543214).
I need my app to look through each char of the string and depending on the number, play a 1 second clip from a .wav file. (This I can manage)
However whenever code comes across the number 2, I require the app to wait for the user to press the screen (or a button) before the .wav file is played, and then carry on playing other .wav files until it comes across a number 2 again or runs out of numbers to play.
I just started out with Android a couple of weeks ago and have read into Services and asynkTasks but I am unsure how to proceed exactly.
Any guidance would be great!
try this -
String song = {"path to sound for 1","path to sound for 2"and so on..}
MediaPlayer mediaPlayer = new MediaPlayer();
int i=0;
//initialise playButton
playButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){ //implement onClick to play first sound
playSong((Integer.parseInt(str.charAt(i++)))-1);
}
}
playSong(int songIndex){
mediaPlayer.reset();
try{
mediaPlayer.setDataSource(song[songIndex]);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
I'm making a simple splash screen so that when an app loads it shows a small logo and plays a little jingle.
I've set it up as so:
splashSong = MediaPlayer.create(MainActivity.this, R.raw.splash);
splashSong.start();
Thread splashThread = new Thread(){
public void run(){
try{
sleep(6000);
}
}catch (InterruptedException e){
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
Intent openMenu = new Intent("com.mmm.MAINMENU");
startActivity(openMenu);
}
}
};
splashThread.start();
However there is an issue with the play count. When it loads the splash class, the jingle is played twice. I've changed a series of things such as preparing the song and setting the datasource. This is, however, not successful and the screen still plays the song twice.
Anybody have any ideas as to why it might be doing this?
Thanks,
Add
splashSong.setLooping(false);
Thanks to Mr. Me for the help. It was to do with the applications orientation. Removed that and all worked!
I have this problem, I have some audio I wish to play...
And I have two buttons for it, 'Play' and 'Stop'...
Problem is, after I press the stop button, and then press the Play button, nothing happens. -The stop button stops the song, but I want the Play button to play the song again (from the start) Here is my code:
final MediaPlayer mp = MediaPlayer.create(this, R.raw.megadeth);
And then the two public onclicks:
(For playing...)
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
button.setText("Playing!");
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
//
}
});
And for stopping the track...
final Button button2 = (Button) findViewById(R.id.cancel);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mp.stop();
mp.reset();
}
});
Can anyone see the problem with this? If so could you please fix it... (For suggest)
Thanks alot...
James
You need to call prepare() or preparAsync() before start().
See the API for details (look at the state diagram).
There is a bug in the Android documentation, in this page it is said that you could stop() a "raw resource" mediaplayer, and then replay it just by calling reset() and prepare() before calling start() again. This doesn't work, as you have noticed.
The problem is that reset() clears the audio source and returns to the initial state, so you must set again the data source. Unfortunatelly you can't set a "raw resource" data source, because there is no API for this besides create().
I don't know a clean way of solving this issue. stealthcopter's way works great, but is a pain for your design, as you need the context for each start() call :( And involves destroying and creating a complex object, which has a price for realtime apps like games...
Another way that ensures that context will only be needed for the create() call, is to stop the media player this way:
stop()
prepare()
but if you call start() now, it won't restart from the beginning. You could call seekTo(0), but the sound will have a bit of noise from the previous play position.
I keep investigating on this. There must be a clean and efficient way of stopping and restarting the mediaplayer when created on a raw resource...
This is what I have working in my program. It releases the media player each time as I use different sounds each time it is called, however it should work as a work-around for your usage.
Creation:
public MediaPlayer mp=null;
Starting:
if (mp!=null){
mp.reset();
mp.release();
}
mp = MediaPlayer.create(test.this, soundResource);
mp.start();
Stopping:
mp.stop();
Also note that you do not require to use prepare because the create method already calls prepare for you (API REF).
I have a button that plays an audio file on its click listener. If the button is clicked again and again while the audio file is being played then the app crashes. What's the solution?
Here is some code for reference:
private OnClickListener btnMercyListener = new OnClickListener()
{
public void onClick(View v)
{
// Toast.makeText(getBaseContext(),
// "Mercy audio file is being played",
// Toast.LENGTH_LONG).show();
if (status==true)
{
mp.stop();
mp.release();
status = false;
}
else
{
mp = MediaPlayer.create(iMEvil.this,R.raw.mercy);
//mp.start();
try{
mp.start();
status= true;
//mp.release();
}catch(NullPointerException e)
{
Log.v("MP error",e.toString());
}
}
mp.setOnCompletionListener(new OnCompletionListener(){
// #Override
public void onCompletion(MediaPlayer arg0) {
mp.release();
status = false;
}
}
);
}
};
Two things:
1. Debug the crash and see where it's failing (which line).
2. Surround the whole statement with a try/catch and simply catch an Exception.
If you have an exception or a better idea where your code is failing, then it will be much easier to give you advice on how to fix it... as a matter of fact, you might not even need advice to fix it, you might end up solving the problem by yourself and then you will reap the fruits of your own success.
Update per comments:
The documentation for MediaPlayer indicates what might be the problem given the symptoms the OP is seeing:
To stop playback, call stop(). If you wish to later replay the media, then
you must reset() and prepare() the MediaPlayer object before calling
start() again. (create() calls prepare() the first time.)
It looks like if the play button is pressed too many times, then the media may end up not being in the prepared state and thus throw some exception. The idea of disabling the play button is valid and it should take care of this situation.
Here is some illustrative code on what you want your program to do:
private OnClickListener btnMercyListener = new OnClickListener()
{
public void onClick(View v)
{
if(isPressed)
{
return;
}
isPressed = true;
// create your media player
mp = MediaPlayer.create(iMEvil.this,R.raw.mercy);
// set your listener
mp.setOnCompletionListener(mp.setOnCompletionListener(new OnCompletionListener(){
// #Override
public void onCompletion(MediaPlayer arg0) {
if(!isPressed)
{
return;
}
isPressed = false;
// re-enable your play button
playButton.enable();
// disable the pause button
pauseButton.disable();
mp.release();
mp.prepare();
}
}
);
// disable the play button
playButton.disable();
// enable the pause button
pauseButton.enable();
// start playback
mp.start();
}
};
Of course you should have the appropriate try/catch statements in there so your app doesn't crash, but this code should give you a general idea of what to do.