I'm totally lost in this. I found the code pretty simple, and didn't find in the documentation any reason why would return a negative number that large. The code is as follows
private int getDuration(String audioPath) throws Exception {
mediaPlayer = new MediaPlayer(); // This variable was created globally
mediaPlayer.setDataSource(audioPath);
return mediaPlayer.getDuration(); // Here it returns -1412558917 in every audio file i record, no matter if it's 3 seconds long or 8
}
I think that it doesn't matter how I record it, but if I'm mistaken I'll add the code. The format I save the file is 3gp. I'm able to reproduce the audio after this, so I don't know what might be the problem
Thanks
Have you tried adding mediaPlayer.prepare(); before you return the duration?
I'm having a hard time with media player in android. Basically I try to play a song from my sd card which is downloading (some sort of streaming). So after the song was downloaded (20%) the song starts to play and if I leave it like this it works fine until the end. But if I try to seek at the end (over 20%) obviously it won't work because my seek position is over EOF file so I made this code inside a method
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(sFilePath);
mp.prepare();
int offset = (progress * mp.getDuration()) / 100;
if (sCompleted) return;
sLastSeek = offset;
if (offset > sMediaPlayer.getDuration()) {
sMediaPlayer.reset();
sMediaPlayer.setDataSource(sFilePath);
sMediaPlayer.prepare();
} else {
sMediaPlayer.seekTo(offset);
}
Where sMediaPlayer is my mediaPlayer, and sFilePath is the file path. In theory the case I presented should be covered but when I seek over the file length the player is reseted (as the code says) but is not playing and this is very awkward and is over my powers.
Maybe the mediaPlayer stopt because it reaches the end of the song. Either start it again, refresh the file in steady intervals (say every 5 secs), or just use onCompletionListener. In the last case, when the file ends, you can reload the file and continue playing... mp.getCurrentPosition() to get where it left off playing.
I also noticed you refer to sMediaPlayer, but your MediaPlayer is defined as mp.
I am programming for android 2.2 and am trying to using the
SoundPool class to play several sounds simultaneously but at what feel like random times sound will stop coming out of the speakers.
for each sound that would have been played this is printed in the logcat:
AudioFlinger could not create track. status: -12
Error creating AudioTrack
Audio track delete
No exception is thrown and the program continues to execute without any changes except for the lack of volume. I've had a really hard time tracking down what conditions cause the error or recreating it after it happens. I can't find the error in the documentation anywhere and am pretty much at a loss.
Any help would be greatly appreciated!
Edit: I forgot to mention that I am loading mp3 files, not ogg.
i had almost this exact same problem with some sounds i was attempting to load and play recently.
i even broke it down to loading a single mp3 that was causing this error.
one thing i noted: when i loaded with a loop of -1, it would fail with the "status 12" error, but when i loaded it to loop 0 times, it would succeed. even attempting to load 1 time failed.
the final solution was to open the mp3 in an audio editor and re-edit it with slightly lesser quality so that the file is now smaller, and doesn't seem to take up quite as many resources in the system.
finally, there is this discussion that encourages performing a release on the objects you are using, because there is indeed a hard limit on the resources that can be used, and it is system-wide, so if you use several of the resources, other apps will not be able to use them.
https://groups.google.com/forum/#!topic/android-platform/tyITQ09vV3s/discussion%5B1-25%5D
For audio, there's a hard limit of 32 active AudioTrack objects per
device (not per app: you need to share those 32 with rest of the system), and AudioTrack is used internally beneath SoundPool,
ToneGenerator, MediaPlayer, native audio based on OpenSL ES, etc. But
the actual AudioTrack limit is < 32; it depends more on soft factors
such as memory, CPU load, etc. Also note that the limiter in the
Android audio mixer does not currently have dynamic range compression,
so it is possible to clip if you have a large number of active sounds
and they're all loud.
For video players the limit is much much lower due to the intense load
that video puts on the device.
I'll use this as an opportunity to remind media developers: please
remember to call release() for media objects when your app is paused.
This frees up the underlying resources that other apps will need.
Don't rely on the media objects being cleaned up in finalize by the
garbage collector, as that has unpredictable timing.
I had a similar issue where the music tracker within my Android game would drop notes and I got the Audioflinger error (although my status was -22). I got it working however so this might help some people.
The problem occurred when a single sample was being output multiple times simultaneously. So in my case it was a single sample being played on two or more tracks. This seemed to occasionally deadlock or something and one of the two notes would be dropped. The solution was to have two copies of the sample (two actual ogg files - identical but both in the assets). Then on each track even although I was playing the same sample, it was coming from a different file. This totally fixed the issue for me.
Not sure why it works as I cache the samples into memory, but even loading the same file into two different sounds didn't fix it. Only when the samples came out of two different files did the errors go away.
I'm sure this won't help everyone and it's not the prettiest fix but it might help someone.
john.k.doe is right. You must reduce the size of your mp3 file. You should keep the size under 100kb per file. I had to reduce my 200kb file to 72kb using a constante bit rate(CBR) of 32kbps instead of the usual 128kbps. That worked for me!
Try
final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 50);
tg.startTone(ToneGenerator.TONE_PROP_BEEP, 200);
tg.release();
Releasing should keep your resources.
I was with this problem. In order to solve it i run the method .release() of SoundPool object after finish playing the sound.
Here's my code:
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 50);
final int teste = pool.load(this.ctx,this.soundS,1);
pool.setOnLoadCompleteListener(new OnLoadCompleteListener(){
#Override
public void onLoadComplete(SoundPool sound,int sampleId,int status){
pool.play(teste, 20,20, 1, 0, 1);
new Thread(new Runnable(){
#Override
public void run(){
try {
Thread.sleep(2000);
pool.release();
} catch (InterruptedException e) { e.printStackTrace(); }
}
}).start();
}
});
Note that in my case my sounds had length 1-2 seconds max, so i put the value of 2000 miliseconds in Thread.sleep(), in order to only release the resources after the player have had finished.
Like said above, there is a problem with looping: when I set repeat to -1 I get this error, but with 0 everything is working properly.
I've noticed that some sounds give this error when I'm trying to play them one by one. For example:
mSoundPool.stop(mStreamID);
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);
In such case, first track is played ok, but when I switch sounds, next track gives this error. It seems that using looping, a buffer is somehow overloaded, and mSoundPool.stop cannot release resources immediately.
Solution:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mStreamID = mSoundPool.play(mRandID, mVolume, mVolume, 1, -1, 1f);
}, 350);
And it's working, but delay is different for different devices.
In my case, reducing the quality and thereby the file sizes of the MP3's to under 100kb wasn't sufficient, as some 51kb files worked while some longer duration 41kb files still did not.
What helped us was reducing the sample rate from 44100 to 22050 or shortening the duration to less than 5 seconds.
I see too many overcomplicated answer. Error -12 means that you did not release the variables.
I had the same problem after I played an OGG audio file 8 times.
This worked for me:
SoundPoolPlayer onBeep; //Global variable
if(onBeep!=null){
onBeep.release();
}
onBeep = SoundPoolPlayer.create(getContext(), R.raw.micon);
onBeep.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) { //mp will be null here
loge("ON Beep! END");
startGoogleASR_API_inner();
}
}
);
onBeep.play();
Releasing the variable right after .play() would mess things up, and it is not possible to release the variable inside onCompletion, so notice how I release the variable before using it(and checking for null to avoid nullpointer exceptions).
It works like charm!
A single soundPool has an internal memory limitation of 1 (one) Mb. You might be hitting this if your sound is very high quality. If you have many sounds and are hitting this limit, just create more soundpools, and distribute your sounds across them.
You may not even be able to reach the hard track limit if you are running out of memory before you get there.
That error not only appears when the stream or track limit has been reached, but also the memory limit. Soundpool will stop playing old and/or de-prioritized sounds in order to play a new sound.
I'm making an Android game-app in which you start as a little fish, and you need to eat smaller fish.
Each time you eat a smaller fish (by swimming against them), a sound plays. This is the code for playing the sound:
mp = MediaPlayer.create(GobbleFishGame.this, R.raw.bite);
if (!mPlaySound) {
return;
}
mp.start();
MPRelease();
This works well for the first few fishes. But after having eaten some fishes (the amount varies, but it's around 8-11 fishes), the game suddenly stops and I get the "Activity GobbleFish (in application GobbleFish) is not responding." error. I think it has something to do with too much resources being allocated to the MediaPlayer, therefore I've created a sub which releases mp's resources, and then creating a new MediaPlayer mp (this sub is called every time a fish is eaten). This is the code for the sub:
private void MPRelease(){
MPReleaseCount += 1;
if(MPReleaseCount==5){
mp.release();
mp = new MediaPlayer();
//mp = MediaPlayer.create(GobbleFishGame.this, R.raw.bite);
//mp.reset();
MPReleaseCount=0;
}
}
When MPReleaseCount is 5, mp gets released and recreated (so after 5 fishes are eaten).
I hoped that this would work, but it doesn't. I still have the problem that after some fishes are eaten (last time was 17 fishes, so MPRelease should have been called 3 times already), I get the "is not responding" error and I have to Force Close or Wait.
Can anyone tell me how I could do this to release the resources? Because I think that's the issue. I can't really tell if that's the issue because I don't get any error message in my LogCat in Eclipse. I did get this error report after Force Closing the app because of a "is not responding" error:
ANR in (my activity)
Reason: keyDispatchingTimedOut
Thanks in advance.
Don't release and create the MediaPlayer everytime you used it. Create it once with your audiosource and call a seekTo(0) in an OnCompletionListener(). Then play it again.
Also have a look at SoundPool http://developer.android.com/reference/android/media/SoundPool.html which is made for usecases like yours where you have to play the same audio multiple times. It stores the audio and plays it on demand. You also have a lower audio latency than with MediaPLayer.
I am using the following code to play audio file.
I have tested the audio file on Android phone player & its playing quite loud.
When I am trying to play the same audio file from the following code , its very feeble.
Is there any problem with my code ? Can I increase the volume of the media file by changing any value ?
While testing , the volume of the Android device has been put to maximum value.
Kindly provide your inputs/sample code.
Thanks in advance.
public void playAlertSound() {
MediaPlayer player = MediaPlayer.create(this, R.raw.beep);
player.setLooping(false); // Set looping
player.setVolume(0.90f, 0.90f);
// Begin playing selected media
player.start();
// Release media instance to system
player.release();
}
Try player.setVolume(1.0f, 1.0f); instead; or just leave off that line entirely. You can also try scaling up the value past 1.0, although that's not really recommended.
You shouldn't call player.release() immediately. Try calling that in your onPause() or onDestroy() methods instead.
You might try using AudioManager.getStreamMaxVolume() to get the maximum volume and use it:
AudioManager audio =
(AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
int max = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
player.setVolume(max, max);
I'm not sure though if setVolume() expects absolute levels or multipliers from 0.0f to 1.0f. It mentions logarithmic adjustment, so you might try something closer to 1.0f like 0.95f or 1.0f itself.