I have a game and I use separate MediaPlayer for each sound
Here it is :
public class SoundSample {
public final static String CORRECT="sounds/correct.wav";
public final static String PASS="sounds/pass.wav";
public final static String CLOCK_OUT="sounds/clock_out.mp3";
public final static String ALARM="sounds/alarm.mp3";
public final static String COUNTDOWN_TO_START="sounds/countdown_to_start.mp3";
public final static String GO="sounds/go.mp3";
private String assetFile;
private MediaPlayer mediaPlayer;
public SoundSample(String sound){
assetFile = sound;
try {
AssetFileDescriptor afd = MainActivity.activity.getAssets().openFd(sound);
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void play(){
if (mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.start();
}
public void release(){
mediaPlayer.release();
mediaPlayer.reset();
mediaPlayer = null;
}
}
so, I use
correctSound = new SoundSample(SoundSample.CORRECT);
and then
correctSound.play();
So, at a second use it stops playing on many phones and never play again. I mean, debugger shows that mediaPlayer.start(); is executed but the sounds never play again.
it works well, however , on every Android 6 phone I tested, so it's probably only a android 6- or 5- issue
Is there any way I can correct this? I know I can use SoundPool, but it also has some issues
You have to recreate the media player , try like below
if (mediaPlayer.isPlaying()) {
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.yourAudio);
}
mediaPlayer.start();
Try to add code
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
i am creating an application that in it i need to play some sounds with low bit rates such as 16kbps.
I use MediaPlayer with below code. but it cannot play and i get Error(100, 0) in logcat. when i replace audio with 48kbps OGG file or 128kbps MP3 file all thing is ok. How i can play audio with 16kbps bit rate?
I have this problem only on Kitkat
player = new MediaPlayer();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
try {
Class<?> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider");
Class<?> cSubtitleController = Class.forName("android.media.SubtitleController");
Class<?> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor");
Class<?> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener");
Constructor constructor = cSubtitleController.getConstructor(new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener});
Object subtitleInstance = constructor.newInstance(activity, null, null);
Field f = cSubtitleController.getDeclaredField("mHandler");
f.setAccessible(true);
try {
f.set(subtitleInstance, new Handler());
} catch (IllegalAccessException ignored) {
} finally {
f.setAccessible(false);
}
Method setsubtitleanchor = player.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor);
setsubtitleanchor.invoke(player, subtitleInstance, null);
//Log.e("", "subtitle is setted :p");
} catch (Exception e) {
}
}
player.setWakeMode(activity,
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
this.seekbar = seekbar;
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
finalTime = player.getDuration();
timeElapsed = mediaPlayer.getCurrentPosition();
seekbar.setMax(finalTime);
init();
remaining.setText(miliToTime(finalTime));
elapsed.setText("0:00:00");
durationHandler.postDelayed(updateSeekBarTime, 100);
}
});
player.setOnErrorListener(this);
player.setDataSource(musicPath);
player.prepareAsync();
I have a list of audio files like this,
int music_numbers[] = { R.raw.one, R.raw.two, R.raw.three, R.raw.four,
R.raw.five, R.raw.six, R.raw.seven, R.raw.eight, R.raw.nine };
I need to play this one by one - when i send 100 to this play_numbers method - i am intend to play digit wise..
I have done this - but i unable to do this one after another..
private void _play_numbers(final String i) {
// TODO Auto-generated method stub
mPlayer = MediaPlayer.create(PlayFileActivity.this, R.raw.payment);
mPlayer.start();
mPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mPlayer.stop();
myDigit = i.charAt(1) + "";
_function_play_file(Integer.parseInt(myDigit));
}
});
}
in _function_play_file - i have this
void _function_play_file(int files) {
switch (files) {
case 0:
mPlayer = MediaPlayer.create(this, music_numbers[0]);
mPlayer.start();
case 1:
mPlayer = MediaPlayer.create(this, music_numbers[1]);
mPlayer.start();
case 2:
mPlayer = MediaPlayer.create(this, music_numbers[2]);
mPlayer.start();
case 3:
mPlayer = MediaPlayer.create(this, music_numbers[3]);
mPlayer.start();
case 4:
mPlayer = MediaPlayer.create(this, music_numbers[4]);
mPlayer.start();
case 5:
mPlayer = MediaPlayer.create(this, music_numbers[5]);
mPlayer.start();
case 6:
mPlayer = MediaPlayer.create(this, music_numbers[6]);
mPlayer.start();
case 7:
mPlayer = MediaPlayer.create(this, music_numbers[7]);
mPlayer.start();
case 8:
mPlayer = MediaPlayer.create(this, music_numbers[8]);
mPlayer.start();
case 9:
mPlayer = MediaPlayer.create(this, music_numbers[9]);
mPlayer.start();
case 10:
mPlayer = MediaPlayer.create(this, music_numbers[10]);
mPlayer.start();
}
}
You need to set an onCompletionListener to each and start the next one on completion.
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
// Code to start the next audio in the sequence
}
});
The best way to achieve this is to create a class that implements OnCompletionListener which handles the onCompletion and receives the next file to play. This way you can instantiate it nicely in your code.
Of course, don't forget your break; in the cases above.
Use a queue for holding the numbers to be played.
private void _play_numbers(final String i) {
// e.g '100': put '1', '0', '0' in a Queue after converting to digits
Queue queue = new LinkedList();
//Use the add method to add items.
myDigit = // remove next digit from queue..
_function_play_file(myDigit);
}
void _function_play_file(int files) {
switch(files) {
case 0:
mPlayer = MediaPlayer.create(PlayFileActivity.this, R.raw.payment);
mPlayer.setOnCompletionListener(completeListener );
mPlayer.start();
break;
.....
}
OnCompletionListener completeListener = new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
myDigit = // remove next digit from queue..
if (myDigit != -1) // if queue is not empty..
_function_play_file(myDigit);
}
});
}
This code works for me,but i place the audio files in assets folder:
//define a variable to be used as index.
int audioindex = 0;
//Extract the files into an array
String[] files = null;
files = assetManager.list("audiofiles");
mp.setOnCompletionListener(new OnCompletionListener(){
// #Override
public void onCompletion(MediaPlayer arg0) {
// File has ended, play the next one.
FunctionPlayFile(files[audioindex]);
audioindex+=1; //increment the index to get the next audiofile
}
});
This is working code for playing songs in continue loop
public class MainActivity extends Activity
{
private int[] tracks = {R.raw.explosion,R.raw.pianothingy_one,R.raw.car_horn_x};
int mCompleted = 0;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaPlayer mp = MediaPlayer.create(this, tracks[0]);
mp.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mCompleted++;
mp.reset();
if (mCompleted < tracks.length)
{
try
{
AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
if (afd != null)
{
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else if (mCompleted>=tracks.length)
{
mCompleted =0;
try
{
AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
if (afd != null)
{
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else
{
mCompleted=0;
mp.release();
mp = null;
}
}
});
mp.start();
use PlayMedia Like this
int[] soundIDs = {R.raw.yes, R.raw.eat};
PlayMedia playAudio = new PlayMedia(context,soundIDs);
playAudio.execute();
and define PlayMedia Class Like this
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.AsyncTask;
import android.util.Log;
public class PlayMedia extends AsyncTask<Void, Void, Void> {
private static final String LOG_TAG = PlayMedia.class.getSimpleName();
Context context;
private MediaPlayer mediaPlayer;
int[] soundIDs;
int idx =1;
public PlayMedia(MediaPlayer mediaPlayer) {
this.mediaPlayer = mediaPlayer;
}
public PlayMedia(final Context context, final int[] soundIDs) {
this.context = context;
this.soundIDs=soundIDs;
mediaPlayer = MediaPlayer.create(context,soundIDs[0]);
setNextMediaForMediaPlayer(mediaPlayer);
}
public void setNextMediaForMediaPlayer(MediaPlayer player){
player.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
if(soundIDs.length>idx){
mp.release();
mp = MediaPlayer.create(context,soundIDs[idx]);
setNextMediaForMediaPlayer(mp);
mp.start();
idx+=1;
}
}
});
}
#Override
protected Void doInBackground(Void... params) {
try {
mediaPlayer.start();
} catch (IllegalArgumentException e) {
Log.e(LOG_TAG, "", e);
} catch (SecurityException e) {
Log.e(LOG_TAG, "", e);
} catch (IllegalStateException e) {
Log.e(LOG_TAG, "", e);
}
return null;
}
}
For me the issue was that I was calling mediaPlayer.prepare() without first calling mediaPlayer.reset().
All good now.
MediaPlayer mediaplayer = new MediaPlayer();
setSound(file );
try {
if(mediaplayer != null)
{
mediaplayer.stop();
mediaplayer.release();
}
mediaplayer.setDataSource(getResources().openRawResourceFd(file)
.getFileDescriptor());
mediaplayer.prepare();
mediaplayer = MediaPlayer.create(getBaseContext(), now);
mediaplayer.start();
mediaplayer.setLooping(false);
mediaplayer.setLooping(true); //sequence playing
} catch (NullPointerException e) {
e.printStackTrace();
}
I need to play random sound out of 300 sounds placed in assets folder.
While implementing the problem I am getting is that its always playing the first sound from assets on button click.
MediaPlayer player;
AssetFileDescriptor descriptor;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.machine);
player = new MediaPlayer();
playSound = (ImageButton)findViewById(R.id.button_play);
AssetManager aMan = this.getAssets();
try
{
filelist = aMan.list("");
} catch (IOException e1) {
e1.printStackTrace();
}
playSound.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(filelist.length);
try
{
String mediaFile = filelist[randomInt];
descriptor = getAssets().openFd(mediaFile);
player.setDataSource(descriptor.getFileDescriptor(),descriptor.getStartOffset(),descriptor.getLength());
descriptor.close();
player.prepare();
player.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
Try changing this line:
filelist = aMan.list("");
to this:
filelist = aMan.list("/assets");
I have several audio files in the res/raw folder.
When I run the following code I was assuming that just the "sound1" file would be played, instead all of the files in the folder get played one after another, not just "sound1".
MediaPlayer mp = MediaPlayer.create(this, R.raw.sound1);
try {
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
What am I missing?
Thanks for any help!
You can try this way.
static MediaPlayer mpBackground = new MediaPlayer();
mpBackground = MediaPlayer.create(this, R.raw.music);
mpBackground.start();
Use SoundPool instead if they are short sound clips... I ran into alot of issues using the Mediaplayer for playing short sounds. I store my sounds in the assets folder instead of res/raw... but you can get the same results. Here is some code.
private int BUZZ = sound_load("sounds/buzz.mp3");
private SoundPool _sounds = new SoundPool(8, AudioManager.STREAM_MUSIC, 0);
private int sound_load(String fname) {
AssetManager am = getAssets();
try {
AssetFileDescriptor fd = am.openFd(fname);
int sid = _sounds.load(fd.getFileDescriptor(), fd.getStartOffset(),
fd.getLength(), 1);
return sid;
} catch (IOException e) {
}
return 0;
}
private void sound_play(int sid) {
_sounds.play(sid, (float) 1.0, (float) 1.0, 0, 0, (float) 1.0);
}
Then to play a sound I just call it like this:
sound_play(BUZZ);