I am getting problems in playing audio(mp3) files this music files are like click sounds its residing at the raw folder, the problem is if there are many clicks at random intervals it throws an exception of nullPointer. It occurs anywhere when the click is done and anytime, is it related to the memory issue or MediaPlayer related problem, pls any suggestion will be appreceated.
Its simple media player object that i m calling, but its a games so on touch it plays the files, so in game i have many things to drag so i want a click sound at that time, sometime it works fine but when exceeds certain limit it throws null pointer exceptions. this is the code:
MediaPlayer mp= MediaPlayer.create(context,R.raw.soun1);
mp.start();
thats it:
just try this ::
MediaPlayer mp = new MediaPlayer();
mp= MediaPlayer.create(this,R.raw.soun1);
mp.start();
permission in manifest file:::
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
To play media player...we need two classes..
let us suppose mainactivity.java is our first file..
here we define two buttons - start_button & stop_button
mButton_start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent mIntent=new Intent(MainActivity.this,maservice.class);
startService(mIntent);
}
});
mButton_stop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent mIntent=new Intent(MainActivity.this,maservice.class);
stopService(mIntent);
}
});
maservice.java is our another java file. Here we define media player and also there should be 3 methods: onCreate(), onStart(), onDestroy().
Here is the code:
MediaPlayer mPlayer;
#Override
public void onCreate()
{
super.onCreate();
mPlayer=MediaPlayer.create(this, R.raw.kyun);
mPlayer.setLooping(true);
}
#Override
public void onStart(Intent miIntent, int startid)
{
super.onStart(miIntent, startid);
mPlayer.start();
}
#Override
public void onDestroy()
{
super.onDestroy();
mPlayer.stop();
}
We also have to define these java files in manifest file
mainactivity.java is defined under activity tag
but maservice.java is defined under service tag
I got my answer, its SoundPool, especially created when the concern of game like application where the sound files are used continuously, so here we should use SoundPool except of MediaPlayer.
The issue is with the MP3 encoding. I tried with the same code, few work and few don't. So please try with a different one if it shows up the same error next time.
Related
I am trying to play some audio in background using two MediaPlayers inside a Service. Everything works fine if I want to play only one mp3, but If I try to play two at the same time, using two instances of MediaPlayer, only the last one works. It is weird because it works in emulator and some devices, but I am unable to make it work in a Nexus 5. This is the code I am using to create the two MediaPlayer instances:
private void playWithPiano() {
mp1 = initializePlayer(filenameVoz); // filenameVoz is the mp3 file name in raw folder
mp2 = initializePlayer("base_piano");
mp1.start();
mp2.start();
}
private MediaPlayer initializePlayer(String filename) {
int identifier = getResources().getIdentifier(filename,
"raw", getPackageName());
MediaPlayer mp = MediaPlayer.create(this, identifier);
mp.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(TAG_LOG, "OnErrorListener");
stop();
return false;
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
stop();
}
});
return mp;
}
If I comment the mp2.start line, then I can listen the mp1 audio. It is like when a MediaPlayer is started, any other instances are stopped I would appreciate any help with this.
I found other posts describing the same problem in Nexus 5 devices, but don't have a solution yet.
https://code.google.com/p/android/issues/detail?id=63099
https://code.google.com/p/android/issues/detail?id=62304
I tried using seekTo(0) like it was suggested in one of those forums, but it didn't work, so I tried another thing that seems like an specific workaround for my case.
I am using this inside a Service, and my second MediaPlayer is only to play some background music, so I started it half second after the first one and it worked.
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
if (mp2 != null) mp2.start();
}
},
500
);
I still don't know why I am having this problem only in the Nexus 5, but I hope this may help somebody.
I am using this setOnClickListener() inside an one of the method in my Android App.Here I have used A mediaPlayer, which is declared locally.
Like this I also have two more methods which all uses mediaplayer. Also I have declared a global Mediaplayer & used it in various places of my onCreate().
public void setOnClickListenerWithMedia(ImageView iv,final int drawable,final int sound) {
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopAllSoundsAndClearMemory();
switchCases();
iv_gone();
fullscreenImage.setVisibility(View.VISIBLE);
fullscreenImage.setImageResource(drawable);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), sound);
mediaPlayer.start();
}
});
}
My problem is if I click on any other method, I have to stop the MediaPlayer. For Globally declared MediaPlayer Object(mp.). I can directly use,
if(mp!=null&&mp.isPlaying()){
mp.stop();
}
and I can stop it. But I also want to stop the sound from all the methods. How is it possible?
P.S: -> If I use mp in all the methods , it is not playing the sound & saying to create static mediaPlayer.
Thank you.
Every time when you are creating new player assign it to Global MediaPlayer instance.
i.e
declare mediaPlayer like this
MediaPlayer mp;
And then in your onClick or in other other methods use like this
And check whether MediaPlayer already exist or not
f(mp!=null&&mp.isPlaying()){
mp.stop();
mp.release();
}
mp=MediaPlayer.create(getApplicationContext(), sound);
mp.start();
try to design your mediaplayer as a singleton mode, and then your mediaplayer will be created only one instance object through the whole app.
I'm trying to create a simple soundboard for my 3 year old and have run into quite a dilema, I thought I had found the best possible way to code the soundboard but have run into an issue when the button is clicked nothing happens??
The code is clean, no indication of errors so I'm at my wits end.
Your help is very much appreciated.
public class Player extends Activity implements OnClickListener {
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button Button1 = (Button)findViewById(R.id.Button1);
Button1.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mp = MediaPlayer.create(this, R.raw.splashsound);
mp.start();
while (mp.isPlaying()){
};
mp.release();
}
};
You need to setup the AudioStream with the setAudioStreamType()
mp = MediaPlayer.create(this, R.raw.ursoundboardtrack);
mp.setAudioStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
mp.prepare();
mp.start();
Have you made sure that your splashsound is in a .wav format ?
If it is'nt then this App will never work as it needs to be in a .wav format not a .mp3 or .wma or any other type of audio format it has to be in a .wav format.
If your splashsound is in another audio format but .wav then you will have to convert it to a .wav and import it back into your project and delete the old one and hopefully it should work :)
I'm working on a project in which I have to load 6 different sounds in one activity and play all sound on button click.The sound file are not so big,but the problem is that maybe they will be more.So my question is which is the fastest way to load sound files in a single activity.For test purposes I used res/raw folder to store the sound files and tried with two different method to play the files,but the result did not satisfied me.Here is the two different types of code :
Method 1:
Button first = (Button) findViewById(R.id.one);
Button second = (Button) findViewById(R.id.two);
first.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(SoundFXActivity.this, R.raw.drumtwo);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
}
});
second.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(SoundFXActivity.this, R.raw.drumone);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
}
});
Method 2:
private SoundPool spool;
private int soundID,soundID2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID = spool.load(this, R.raw.drumone, 1);
soundID2 = spool.load(this, R.raw.drumtwo, 1);
Button three = (Button) findViewById(R.id.three);
three.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Sound();
}
});
}
public void Sound(){
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float volume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
spool.play(soundID, volume, volume, 1, 0, 1f);
};
But the problem is that the both methods are slow..I need to find a way a faster way to play the sounds..but now there is like almost a second after I click the button to play the sound.
Can you give me some advice how to play the sounda faster.Should I load them into a cache when the application starts or save them in database or somewhere else (I don't think database is a good option as a matter of fact,but I want to hear some suggestions).Or maybe load them from assets folder,but I think it still going to be slow.
So any ideas or suggestions?
Thanks in advance!
You could create the media players in your onCreate and then the buttons will just make them play. That would be the easiest solution, I would say.
Alternatively, depending on how important it is to you and how much work you want to do, you could consider using JetPlayer:
here's android development page for media:
http://developer.android.com/guide/topics/media/index.html
The page on the JetPlayer class:
http://developer.android.com/reference/android/media/JetPlayer.html
and the page on creating the JET files:
http://developer.android.com/guide/topics/media/jet/jetcreator_manual.html
If you implemented this it would likely work best but would definitely be the most work.
JetPlayer basically lets you have one audio file (i think it's a MIDI file) with multiple tracks that you mute and unmute as you please. I have no personal experience with it and have just read the docs some, but it seems like it would be very useful for any situation with more than one sound.
Edit: Also, it's worth mentioning this mailing list and in case the link ever changes this google search in case anyone is interested in android audio topics.
If you want to have the less delay you must use OpenSL in c++, From jelly bean is the faster sound player
SoundPool is working fine, you can see an example with the Hexiano project. However, you must preload the sounds into SoundPool, because it takes a lot of time to decode the file and store them in-memory before being able to use them. But once the sounds are loaded, there's no noticeable delay between key press and sound output.
I'm trying to create a simple Sound-board Android app, using ListView items as buttons. (Btw, I'm a novice programmer)
The idea is that I press a button, and a specific sound file plays. If I press any button while a sound is playing, it should first stop that sound and then start to play the new one.
Currently the sounds play without stopping any currently playing sounds, so that if I spam the buttons I get multiple sounds playing at the same time (and if I press too many at once, the app force closes).
I have tried using a few variations of:
if (mp.isPlaying()) {
mp.stop();
}
But according to what I read on a few other sources, I am creating multiple instances of the MediaPlayer class, and even though they have the same name the stop() method tries to stop on the latest instance of mp (in some cases it isn't even created yet).
I'm guessing my general implementation of the MediaPlayer class is wrong, but it's the best I could figure out to do.
Anyways, here's the relevant block of code:
public class soundTest extends Activity {
private ListView lv1;
private String lv_arr[]={"test 1","test 2","test 3","test 4","test 5"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv1=(ListView)findViewById(R.id.ListView01);
lv1.setAdapter(new ArrayAdapter<String>(this,R.layout.list_item, lv_arr));
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
if (lv1.getItemAtPosition(position)=="test 1") {
MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound1);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
if (lv1.getItemAtPosition(position)=="test 2") {
MediaPlayer mp = MediaPlayer.create(getApplicationContext(),R.raw.sound2);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}
//And the rest of the sounds 3,4,5.
}
});
}
}
Any help would be appreciated, thanks.
Edit (22nd March):
I've found the following piece of code that should work:
mp.setDataSource(context, Uri.parse("android.resource://" + Config.PACKAGE + "/" + resId));
But, I can't figure out how the "Config.PACKAGE" part works. I just get an error "PACKAGE cannot be resolved, or is not a field".
I tried replacing "PACKAGE" with the package name, same error. I also tried:
try {
mp.setDataSource(getApplicationContext(),Uri.parse("android.resource://com.mptest/" + R.raw.test2));
} catch (IOException e) {
e.printStackTrace();
}
But I can't work what exactly to put in place of "//com.mptest/".
The global variable MediaPlayer needs to be set private static. This has caught me several times.
Don't use a global. Use the singleton pattern. That is what it is for, so that you can have exactly one instance w/o using a global variable.
There are lots of good examples of Java code for this pattern, start with http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html and you can't go wrong.
Consider keeping your MediaPlayer as a global variable instead of having multiple instances of it.
You might find a good reference in the VideoView Source, since it handles one MediaPlayer object and you may change content during playback.