I set a music file to loop on MediaPlayer for my game, but it causes a 2 sec delay when it loops.
My code:
boolean activateSounds = getIntent().getBooleanExtra("Activate sounds", true);
if(mp!=null){
mp.reset();
mp.release();
}
mp = MediaPlayer.create(StartGame.this, R.raw.music1);
mp.setVolume(8f, 8f);
mp.setLooping(true); // This is causing delays
if (activateSounds) mp.start();
For a game, this is not interesting. Is there a way to make MediaPlayer run out of loop delays?
I was not able to make setLooping work without a gap.
Only solution that worked for me was to use setNextMediaPlayer call (which is able to start next loop without a gap) and two MediaPlayers.
'pseudo' code:
class Abc implements MediaPlayer.OnCompletionListener {
private final MediaPlayer[] mps = new MediaPlayer[2];
public Abc() {
mps[0] = new MediaPlayer();
mps[1] = new MediaPlayer();
mps[0].setOnCompletionListener(this);
mps[1].setOnCompletionListener(this);
}
public void start()
initMediaPlayer(mps[0]);
initMediaPlayer(mps[1]);
mps[0].setNextMediaPlayer(mps[1]);
mps[0].start();
}
private void initMediaPlayer(MediaPlayer mp)
{
if (mp.isPlaying()){
mp.stop();
}
mp.reset();
final float volume = 0.07f;
mp.setDataSource(MY_SOURCE);
mp.setVolume(volume, volume);
mp.setLooping(false);
try {
mp.prepare();
}catch(Exception error){
Log.d("BackgroundMusic", error.toString());
}
}
#Override
public void onCompletion(MediaPlayer mp)
{
MediaPlayer cur = mps[0] == mp ? mps[1] : mps[0];
initMediaPlayer(mp);
cur.setNextMediaPlayer(mp);
}
}
Related
I want to play and stop the default sound with following rules:
If the sound is not playing, let play it in 10 seconds.
If the sound is playing, let stop it and play at the first position.
Based on these above rules, I design a function as follows:
public MediaPlayer mp =null;
public void playDefaultSound(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
mp = MediaPlayer.create(getApplicationContext(), notification);
try {
if (mp.isPlaying()) {
mp.stop();
mp.release();
mp = MediaPlayer.create(getApplicationContext(), notification);
}
mp.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mp.stop();
mp.release();
}
}, 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
But sometime I still listen two sound are playing (in case of the first sound play and I call the playDefaultSound() function again). Do you think is it correct to delete the mp = MediaPlayer.create(getApplicationContext(), notification); bellow mp.release()? How could I correct the function to satisfy these rules? Thanks all
final MediaPlayer mp = new MediaPlayer();
public void playDefaultSound(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
try {
if (mp != null && mp.isPlaying()) {
mp.seekTo(0);
} else {
mp.reset();
mp.setDataSource(getApplicationNotification(), notification);
mp.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mp.stop();
mp.release();
}
}, 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
P.S. - Always see the state diagram or lifecycle of things whenever stuck.
Ref : [Android Media Player State Diagram][1]
[1]: https://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram "MediaPlayer State Diagram"
I m making an app which is supposed to play a few sounds with the mediaPlayer.
This is the code i use :
String[] name = {"sonar_slow","sonar_medium","sonar_fast"};
String link = "/res/raw/" + name[state-1] + ".mp3";
try {
player.setDataSource(link);
player.prepare();
player.start();
} catch(Exception e) {
e.printStackTrace();
}
I also tried this :
if(state==1){
player.create(this, R.raw.sonar_slow);
}else if(state==2){
player.create(this, R.raw.sonar_medium);
}else if(state==3){
player.create(this, R.raw.sonar_fast);
}
player.start();
But none of the above is working. My app is not crashing but the sound is not playing.
Any ideas ?
There are two problems.
Problem 1
You cannot reference resources inside your projects /res/raw directory in this fashion. The file "/res/raw/sonar_slow.mp3" in your project directory is not stored in "/res/raw/sonar_slow.mp3" in your apk. Instead of the following:
MediaPlayer mp = MediaPlayer.create(this);
mp.setSource("sonar_slow");
You need to use
MediaPlayer mp = MediaPlayer.create(this, R.raw.sonar_slow);
Problem 2
The following is wrong: it calls a static method that does not modify the player.
player.create(this, R.raw.sonar_slow);
You should instead call
player = MediaPlayer.create(this, R.raw.sonar_slow);
Full solution
Below is a reusable AudioPlayer class that encapsulates MediaPlayer. This is slightly modified from "Android Programming: The Big Nerd Ranch Guide". It makes sure to remember to clean up resources
package com.example.hellomoon;
import android.content.Context;
import android.media.MediaPlayer;
public class AudioPlayer {
private MediaPlayer mMediaPlayer;
public void stop() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void play(Context c, int rid) {
stop();
mMediaPlayer = MediaPlayer.create(c, rid);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
stop();
}
});
mMediaPlayer.start();
}
}
How to play a file with MediaPlayer:
MediaPlayer mp = MediaPlayer.create(this, R.raw.mysound); // sound is inside res/raw/mysound
mp.start();
This is a simple example of how to play a sound with the Android MediaPlayer.
You have two buttons hat each play a different sound. The selecting of the sound and actually playing it is done in the manageSound() method. The sounds "hello", "goodbye" and "what" are in the res/raw directory:
MediaPlayer mp = null;
String hello = "Hello!";
String goodbye = "GoodBye!";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button buttonHello = (Button) findViewById(R.id.idHello);
buttonHello.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(hello);
} // END onClick()
}); // END buttonHello
final Button buttonGoodBye = (Button) findViewById(R.id.idGoodBye);
buttonGoodBye.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(goodbye);
} // END onClick()
}); // END buttonGoodBye
} // END onCreate()
protected void manageSound(String theText) {
if (mp != null) {
mp.reset();
mp.release();
}
if (theText.equals(hello))
mp = MediaPlayer.create(this, R.raw.hello);
else if (theText.equals(goodbye))
mp = MediaPlayer.create(this, R.raw.goodbye);
else
mp = MediaPlayer.create(this, R.raw.what);
mp.start();
}
Taken from here: http://www.badprog.com/android-mediaplayer-example-of-playing-sounds
Furthermore, I would strongly recommend using SoundPool instead of MediaPlayer, for better Performance and usability.
http://developer.android.com/reference/android/media/SoundPool.html
Please also check if your sound is muted - I know this sounds stupid, but it happens to the best of us ;)
You need to do it like this :
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();
Make sure your only playing when the file has finished preparing.
I have a simple mp service to play, pause, resume audio. All works fine.
But, last night I have decided to add a feature for user to route audio to ear-piece or speaker and have been battling with mp.setAudioStreamType().
Problem is that I can't change it while service connected and mp created. I don't want to terminate service and/or unbind and rebind as it would require a lot of refactoring
How do I supposed to change AudioStreamType while playing an audio?
Here is my code:
Player service:
public class PService extends Service {
private MediaPlayer mp = new MediaPlayer();
public static final String PLAYING_FINISHED_MSG = "1";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
mp.stop();
mp.release();
}
private void playSong(String file) {
try {
mp.reset();
mp.setDataSource(file);
mp.setAudioStreamType(MYAPP.getAudioStreamType());
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
Intent i = new Intent();
i.setAction(MDService.PLAYING_FINISHED_MSG);
sendBroadcast(i);
}
});
toggle route button onclick
currentlyPlayingFile = file;
currentlyPlayingPhone = phone;
lastDurationBeforePause = mpInterface.getCurrentPosition();
if(MYAPP.getAudioStreamType() == AudioManager.STREAM_MUSIC)
{
MYAPP.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
recording_player_route_button.setImageResource(R.drawable.route_off);
}
else{
MYAPP.setAudioStreamType(AudioManager.STREAM_MUSIC);
recording_player_route_button.setImageResource(R.drawable.route_on);
}
try {
mpInterface.playFile(file);
player_seekbar.setProgress(0);
player_seekbar.setMax(mpInterface.getDuration());
//seekto last millisecond after switching from/to sepaker
if(seekTo>0)
{
mpInterface.seekTo(seekTo);
}
isPauseButtonPressed = false;
handleSeekBarUpdate.postDelayed(handleSeekBarUpdateJob, 1);
} catch (RemoteException e) {
e.printStackTrace();
}
The MODIFY_AUDIO_SETTINGS permission is needed in the Manifest for this to work.
AudioManager am=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_NORMAL);
MediaPlayer mp=new MediaPlayer();
Uri ringtoneUri=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
try
{
mp.setDataSource(getApplicationContext(), ringtoneUri);
mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mp.prepare();
mp.start();
}
catch(Exception e)
{
//exception caught in the end zone
}
i am playing mp3 sound using default media player of android, my code for plying sound below
MediaPlayer mp=MediaPlayer.create(hello.this,R.raw.abc);
if(mp!=null)
{
mp.start();
}
i need to play same sound on same button click. when i click continuously on button after some time sound is not working and i getting error MediaPlayer(7395): error (-19, 0).
Does any body have idea for this issue,
Please send me
Thank in advance.
call
mp.reset();
because ever time you are decalaring object
or declare on class level Mediaplayer OBject
Make global variable of mediaplayer and try this way
MediaPlayer mp;
if (mp!=null) {
mp.stop();
mp.release();
}
mp= MediaPlayer.create(hello.this,R.raw.abc);
mp.start();
mp = new MediaPlayer();
mp.create(this, R.raw.testmed);
mp.setVolume(100, 100);
mp.setOnPreparedListener(this);
mp.prepare();
Then you will need to define this and it should work:
public void onPrepared(MediaPlayer player) {
mp.start();
}
you can play music like below
// for play the song
MediaPlayer mp = new MediaPlayer();
try
{
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
btnPlay.setBackgroundResource(R.drawable.img_btn_pause);
} catch (IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
I have found solution for this issue. i have correct this issue using below code, May help other also.
Thanks
Call Method like
PlaySound(R.raw.abc);
//Method
private void PlaySound(int Sound_id)
{
mplayer = MediaPlayer.create(Act_Oceanwaves.this,Sound_id);
if(mplayer!=null)
{
mplayer.start();
}
mplayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mp.release();
}
});
}
E/MediaPlayer(20473): error (-19, 0)
I/MyApp (20473): Decoding lala.mp3
I/StagefrightPlayer( 68): setDataSource('mypath')
E/AudioFlinger( 68): no more track names available
E/AudioTrack( 68): AudioFlinger could not create track, status: -12
E/AudioSink( 68): Unable to create audio track
Does any1 know why i'm getting this? This usually happens after playing about 100+ of so audio files using mediaPLayer. I'm playing it like this
public RenderResultFormat DoIt() {
if(mp!=null){
mp.release();
mp = null;
}
AudioRenderer mr = new AudioRenderer(); mp = mr.AudioRenderer(filePath);}
private class AudioRenderer extends Activity {
private MediaPlayer AudioRenderer(String filePath) {
//delcare mediaplayer variables, path etc
mp= MediaPlayer.create(this, path);
if(mp != null){
int duration = mp.getDuration();
mp.start();
try {
Thread.sleep(duration);
} catch (InterruptedException e2) {
e2.printStackTrace();
System.out.println("I've been interrupted >:(");
}
}
}return mp;}
Am i missing something? Quite new to android development. Thank you
This solution works well for me (playing a ressource). Just implement an OnCompletionListener
private void playbeep(int id) {
MediaPlayer mPlayer;
mPlayer = MediaPlayer.create(context, id);
mPlayer.start();
mPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}