I'm currently developing application and i want to control playing sound file on different headphones sides ex the first time on the left side and second time on the right side is there any way to achieve this ?
Yes there is a way. MediaPlayer.setVolume(float leftVolume,float rightVolume).
In the following snippet we're playing an .mp3 file contained in assets folder(note if you have multiple files in the folder you should check this answer). By pressing one of the Button objects the song is played only out of the left or the right headphone :
MediaPlayer AudioObj = new MediaPlayer();
AudioObj.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mediaPlayer) {
findViewById(R.id.progressBar).setVisibility(View.INVISIBLE);
Button btnl = (Button) findViewById(R.id.btnPlayleft);
Button btnr = (Button) findViewById(R.id.btnPlayright);
btnl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mediaPlayer.setVolume(1, 0);
mediaPlayer.start();
}
});
btnr.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mediaPlayer.setVolume(0, 1);
mediaPlayer.start();
}
});
}
});
AudioObj.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
AssetFileDescriptor afd = getAssets().openFd("audio.mp3");
AudioObj.setDataSource(afd.getFileDescriptor());
}catch (IOException e){}
AudioObj.prepareAsync();
P.S.
The audio file must be stereo.
Whether you want to check if the headset are plugged or not before playing the audio in order to prompt a message or do something else :
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(!audioManager.isSpeakerphoneOn()){
//prompt a message or do something else
}
Related
I am working on an app that has included an radio and everything is fine the play, stop, and pause buttons. My problem is that whenever a song is playing and I press the back button and reopen the app the buttons won't work with the current streaming radio
This happens as well when I change the orientation. Is there a way I can save the state of the media player and then obtain the state so that I can stop the song that is being played?
public class radioActivity extends AppCompatActivity {
Button b1;
private Button Button1;
private Button Button2;
private String STREAM_URL = "http://192.99.35.93:6370/;stream.mp3";
private MediaPlayer mPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
Button button1 = (Button) findViewById(R.id.buttonpredica1);
Button button2 = (Button) findViewById(R.id.buttonpredica2);
mPlayer = new MediaPlayer();
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
WifiManager.WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
wifiLock.acquire();
wifiLock.release();
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mPlayer.reset();
mPlayer.setDataSource(STREAM_URL);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mPlayer) {
mPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
This happens because every time you either press back or rotate your device, your activity is destroyed and with it goes all of its state. If you want your app to keep playing under such circumstances (which makes total sense for a radio app), you'll need to implement the media playback logic in a service:
https://developer.android.com/guide/components/services.html
Regarding your need to deal with media playback in background, there is a very complete official documentation page on this topic:
https://developer.android.com/guide/topics/media/mediaplayer.html
Create a new object or class that is not GUI related that handles the radio.
in the constructor of your GUI add a parameter MediaPlayer that then sets the respective field to the Media Player.
Adjust the code of the buttons to interact with the Media Player Field.
This will allow for you to open/close various windows that interact with the same MediaPlayer.
public radioactivity(MediaPlayer mPlayer) {
this.mPlayer = mPlayer;
}
This question already has answers here:
Media Player start stop start
(8 answers)
Closed 6 years ago.
I have a button when clicked it plays an audio, and while it is playing I can pause it and replay it again and so forth. I have a shake event, where I want to play the audio on shake and replay it when device is shaken again (by first stopping the audio, calling stopAudio?)
I have the following code:
llBtn = (LinearLayout) findViewById(R.id.button);
llBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(MainActivity.this, "LL WAS CLICKED", Toast.LENGTH_SHORT).show();
//IF AUDIO IS NOT PLAYING... PLAY AUDIO
if (tvPS.getText() == "Stop Phrase!") {
StopAudio();
}
else {
PlayAudio();
}
}
});
//the same button is clicked to stop, it is currently setting to Pause.
public void StopAudio() {
mediaPlayer.pause();
Toast.makeText(MainActivity.this, "STOPPED", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
}
public void PlayAudio() {
//stopPlaying(mediaPlayer);
tvPS.setText("Stop Phrase!");
inResId = getResources().getIdentifier("play" , "raw", getPackageName());
mediaPlayer = MediaPlayer.create(getBaseContext(), inResId);
mediaPlayer.seekTo(0);
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
tvPS.setText("Play Phrase!");
mediaPlayer.pause();
}
});
}
...
public void onShake() {
// Do stuff!
Toast.makeText(getBaseContext(), "Motion detected",
Toast.LENGTH_SHORT).show();
if (mediaPlayer == null) {
PlayAudio();
}
}
How can I modify the code above to handle Play, and then stop if stopped in the middle and then able to replay it again.
The button click works but I am creating a new instance each time and not recycling. When the device is shaken, it plays the audio twice instead of just once.
First of all create the MediaPlayer in onCreate of the context and not in some listener, and don't forget to release it when done, since it consumes a lot of resources,
mediaPlayer.release();
mediaPlayer = null;
Next thing, stop the audio using the stop() function instead of the pause() on completion of the song.
Steps
If you are using a service/activity to play a video create a MediaPlayer instance before it's usage begins, likely in onCreate.
Later use that instance to play/pause/stop the media.
In the onStop of the Service/Activity release the MediaPlayer instance.
Update your playMusic() function to use the MediaPlayer instance you just created, also in the listener use stop() instead of pause()
To change track of an existing MediaPlayer instance
You can use this:
String path = getExternalFilesDir(null).toString()+"/";
mMediaPlayer.setDataSource(path + mediafile);
Link: Changing data source for audio playback using existing MediaPlayer?
i have a button that plays a sound.
When i push the button multiple times, it plays the sound multiple times.
This is oke, i want this.
But when i click the stop button it must stop all sounds currently playing.
I used:
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
but it is not working, the sounds keep on playing. Can someone help me?
Here is my full code:
public class HelloSoundboard extends Activity {
MediaPlayer mediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mediaPlayer.start();
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
// mediaPlayer.stop();
}
});
}
}
SoundPool is a much better alternative for this purpose. I would caution strongly against instantiating multiple MediaPlayer instances as most systems do not have the resources to generate many parallel active instances. You wil find on many device that hitting the button upwards of 5 times will cause a memory based crash.
As far as stopping all active streams, there is not baked-in function for this, but it's easy to accomplish in a manner to similar to your existing code. As a side note, there is an autoPause() method, which halts all streams, but it doesn't truly end their playback (as the method name insinuates). Here is a simple example to manage your audio streams:
//SoundPool initialization somewhere
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//Load your sound effect into the pool
int soundId = pool.load(...); //There are several versions of this, pick which fits your sound
List<Integer> streams = new ArrayList<Integer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int streamId = pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
streams.add(streamId);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (Integer stream : streams) {
pool.stop(stream);
}
streams.clear();
}
});
It is much more memory efficient to manage a list of streamID values than MediaPlayer instances, and your users will thank you. Also, note that it is safe to call SoundPool.stop() even if the streamID is no longer valid, so you don't need to check for existing playback.
HTH
I'm not sure about this, but I think is better if you use a SoundPool.
"SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games".
"MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files".
You can use a list of MediaPlayers:
List<MediaPlayer> mps = new ArrayList<MediaPlayer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mp.start();
mps.add(mp);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (int i = mps.size() - 1; i >= 0; --i) { //changed ++i to --i
if (mps.get(i).isPlaying()) {
mps.get(i).stop();
}
mps.remove(i);
}
}
});
I am currently working on an application for Android and I'm using Eclipse and of course Android SDK, but I have bumped in to a problem that is almost the only thing I need to fix before I can relaese a beta-version to Android Market.
So, my problem is that I have an xml with 4 different buttons, and if the user press on a certain button, one sound will be played, and if the user press any of the other buttons is pressed another sound will play but the sound only play sometimes, I want it to play every time the user press a button.
Here's my code(concerning the mediaplayer):
public MediaPlayer right=null;
public MediaPlayer wrong=null;
if(right!=null) {
right.reset();
right.release();
}
if(wrong!=null) {
wrong.reset();
wrong.release();
}
right = MediaPlayer.create(getBaseContext(), R.raw.rightsound);
wrong = MediaPlayer.create(getBaseContext(), R.raw.wrongsound);
if(****()){
right.start();
}
else {
wrong.start();
}
That's my code and I would be very grateful if somebody could help me solve my problem.
new Thread() {
public void run() {
int sound = R.raw.wrongsound;
if(****()) {
sound = R.raw.rightsound;
}
mp = MediaPlayer.create(Test.this, sound);
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.start();
}
}.start();
How do I set up an audiofile to play when a user touches an image.
Where should I store the audio file and what code should I use to actually play the file?
I don't want to bring up the MediaPlayer interface or anything like that.
I was thinking of doing it like this:
foo = (ImageView)this.findViewById(R.id.foo);
foo.setOnClickListener(this);
public void onClick(View v) {
if (foo.isTouched()) {
playAudioFile();
}
}
Thanks
This won't create a bring up the MediaPlayer interface... it will just play the sound you want.
Button boton = (Button) findViewById(R.id.boton);
boton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(TestSonido.this, R.raw.slayer);
mp.start();
}
});
In this case, R.raw.slayer represents an audio file called slayer.mp3 that is stored in the res/raw/ folder and once you click the button the droid will rock you...
You can also achieve the same using SoundPool.
MediaPlayer first loads the whole sound data in memory then play, so it produces some lag when we switch among sounds frequently.
SoundPool is a better option with small size sound file and produces better result with .ogg media file.
SoundPool pl = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
// 5 indicates the maximum number of simultaneous streams for this SoundPool object
pl.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// The onLoadComplet method is called when a sound has completed loading.
soundPool.play(sampleId, 1f, 1f, 0, 0, 1);
// second and third parameters indicates left and right value (range = 0.0 to 1.0)
}
});
Button btn = findViewById(R.id.boton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int sound = pl.load(this, R.raw.sound_01, 0);
}
});
public void aud_play(View view) {
if (!mp.isPlaying()) { //If media player is not playing it.
mp = MediaPlayer.create(this, R.raw.audio_name);
mp.start();
} else {// Toast of Already playing ...
}
}