No error event when WiFi connection is lost for MediaPlayer - java

I have registered an OnErrorListener with my MediaPlayer and to test it I simply turn off the WiFi. There is no other Internet connection available than WiFi so the playback stops, but the event handler is not fired. Isn't that supposed to happen or how would I deal with these problems?
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(uri);
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
// logging stuff
return false;
}
});
mp.prepare();
mp.start();

I think that the MediaPlayer class does not count that as an error. You could try using setOnBufferingUpdateListener. According to the documentation, this is called
when the status of a network stream's buffer has changed.

Related

Android Mediaplayer Selecttrack method fails

I am using the mediaplayer feature on Android. I basically have songs in the raw folder and I would just like to change to a new track but it fails. One music file plays and then I press a button after or during the music playing to skip to a random track but it fails.
Current code
mediaplayer.stop();
try {
mediaplayer.prepareAysn();
mediaPlayer.selectTrack(randomtrack_num - 1);
}
catch(Exception e){}
mediaplayer.start();
The error that I receive:
MediaPlayer: start called in state 64
MediaPlayer: error (-38, 0)
MediaPlayer: Error (-38,0)
I tried this without mediaplayer.stop() and still included mediaplayer.start() at the end and it would just replay the same track again.
Am I missing something?
Please let me know.
2nd Approach
After reading the document I realized this can only be done in the prepared state which I assume in my second approach it should work but it is not.
mediaPlayer.stop();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
try{
mp.selectTrack(randomtrack_num - 1);
}catch(Exception e){}
mp.start();
}
});
mediaPlayer.prepareAsync();
I get this error:/MediaPlayer: Should have subtitle controller already set
Basically the same track plays again and it does not go to the selected track.
You are calling mediaplayer.start() in wrong state. Firstly read this documentation:
https://developer.android.com/reference/android/media/MediaPlayer.html
You will have a better idea of correct implementation.
EDITED:
String[] url ; // initiliaze your URL array here
MediaPlayer myMediaPlayer = new MediaPlayer();
myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
myMediaPlayer.setDataSource(url[0]);
myMediaPlayer.prepareAsync(); // might take long! (for buffering, etc)
} catch (IOException e) {
Toast.makeText(this, "mp3 not found", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
//mp3 will be started after completion of preparing...
myMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
player.start();
}
});
Playing different track after completions
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp)
{
myMediaPlayer.reset();
/* load the new source */
myMediaPlayer.setDataSource(url[position]);//select the path according to your need
/* Prepare the mediaplayer */
myMediaPlayer.prepareAsync();
}

Android: MediaPlayer reloads remote resource

i am using the MediaPlayer class to loop music from youtube. So far no problem, but the MediaPlayer downloads the video every playback again from youtube, which causes a lot of traffic. Is there a way to let the video in the buffer of the MediaPlayer?
I'm using the following code:
try {
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("http://r6---sn-4g57knsy.googlevideo.com/videoplayback?itag=18&key=yt5&ip=123.45.67.89&ipbits=0&ratebypass=yes&ms=au&source=youtube&sver=3&mt=1383664037&id=3fa390e8443132e0&expire=1383690428&sparams=gcr%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=935610%2C932206%2C916807%2C941242%2C916623%2C924616%2C907231%2C907240&mv=m&gcr=de&upn=9y98yq_WFEc&signature=98E548B5E368061D425FED483828E6D5AF1BBC2B.8AB359B7BA604F108D85578BC704844308E9B6EB");
mp.setLooping(true);
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mp.prepare();
} catch (Exception e) {
e.printStackTrace();
}
Thanks.
Short answer: no.
Long answer: write a simple proxy server to run on the device and cache it yourself. It's not incredibly hard, but it requires some thought to pull off seemlessly.

Error with MediaPlayer

I am trying to make music play in my app and have a song play after the first one has finished but i get some errors that i cannot resolve any help?
public class Music {
int count;
String[] titles = new String[] { "title1.mp3", "title2.mp3", "title3.mp3", "title4.mp3" };
public void GameMusic(){
count = 0;
MediaPlayer mp = MediaPlayer.create(this, R.raw.title1);
mp.start();
}
void onCompletion(MediaPlayer mp){
mp.stop();
if (count == titles.length -1) {
count = 0;
}
mp.setDataSource(titles[count]);
count++;
mp.prepare();
mp.start();
}
}
The errors are on:
MediaPlayer mp = MediaPlayer.create(this, R.raw.music);
(The method create(Context, int) in the type MediaPlayer is not applicable for the arguments (Music, int)
mp.setDataSource(titles[count]);
(Unhandled exception type IOException)
mp.prepare();
(Unhandled exception type IOException)
Any help would be appreciated.
Well the errors might be a little cryptic but they are self-explanatory.
You need to pass a Context to GameMusic() and use it to initialize MediaPlayer:
public void GameMusic(Context context){
count = 0;
MediaPlayer mp = MediaPlayer.create(context, R.raw.title1);
mp.start();
}
this only works if the class (in this case Music) extends Context, so you need to provide a Context another way.
And in onCompletion() use a try-catch block to handle the IOException:
try {
mp.setDataSource(titles[count]);
count++;
mp.prepare();
mp.start();
}
catch(IOException e) {
// Do something when MediaPlayer fails
}
Your Music Class is just a class and not an activity and hence the this passes an object and not a context. If this is your only music player class then you need it to extend Activity else you need to pass a context to it.
public void GameMusic(Context context){
count = 0;
MediaPlayer mp = MediaPlayer.create(context, R.raw.title1);
mp.start();
}
And for the other two exceptions, it states that the exceptions are unhandled. so you need to use a Try-Catch block the handle the uncaught IOException.
That should solve all the errors that you are getting now.
when setting the datasource to Mediaplayer try to use absolutepath of the music file
if it is stored in sd-card means ..try this
String ExternalStorageDirectoryPath = Environment.getExternalStorageDirectory()
.getAbsolutePath();
mp.setDataSource(ExternalStorageDirectoryPath +"/"+titles[count]);
after calling the
mp.prepare();
implement the onpreparedlistner ,after get the notification for this then start the mediaplayer
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
and handle the all kind of exception, so that u can easily track the issues.

MediaPlayer Volume issue-AudioStream issue

I am trying to provide a custom beep sound when I get a message in my Application. This beep sound should respect the master phone notification volume level(not ringer volume). Which means if phone notification vol =3/10 , then beep intensity should be 3/10.
I am not able to achieve this,
AudioManager audioMan = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int volume;
if (mPlayer == null) {
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
if (mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.release();
mPlayer = MediaPlayer.create(context, R.raw.mytone);
}
volume = audioMan.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
mPlayer.setVolume(volume, volume);//this doesn't work for me, beep sound is taking media player volume by default.
mPlayer.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer player, int what, int extra) {
player.stop();
player.reset();
return true;
}
});
if (mVibrator == null)
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.cancel();
Can you please share your knowledge and give me directions. Thank you.
It looks like you are playing your sound over the music stream going by the reference to AudioManager.STREAM_MUSIC. Modifying the volume level modifies the level for everything played on that stream. This is why music/media playback is 'mucked up'.
If you want to use the ringer stream (and its volume setting) then you should be using AudioManager.STREAM_RING instead. You say you've tried this but the code snippet you've given just adjusts the volume - you've not shown how you create and configure your MediaPlayer before you ask it to play your sound.
You've got to select the appropriate stream when you set up your MediaPlayer instance. As I've successfully used different streams in the kind of scenario you are describing, this is where your problem lies. To select the audio stream over which your custom beep is played, use setAudioStream on your MediaPlayer instance like this:
// Get a reference to the MP3 file to play
AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(R.raw.my_mp3);
// Create the media player
MediaPlayer mediaPlayer = new MediaPlayer();
// Give it the MP3 you want played
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// Set the audio stream to play over
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
// Now play the sound
mediaPlayer.prepare();
mediaPlayer.start();
Its good practice to offer your users the option to choose the stream for themselves - in addition to the music and ringer streams there are alarm and notification streams, each with an independent volume level (there are others too, but these are the core ones). Have a look at the Android documentation on AudioManager here.

App with media Player forces down

case R.id.btn7:
if (mp != null && mp.isPlaying()) mp.stop();
mp = MediaPlayer.create(a.this, R.raw.aaaa);
mp.start();
break;
case R.id.btn8:
if (mp != null && mp.isPlaying()) mp.stop();
mp = MediaPlayer.create(a.this, R.raw.bbbb);
mp.start();
break;
How could I use setDataSource in order to stop my app for force close? Please help!
If I use it like this, eclipse highlights red the setDataSource;
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn:
if (mp != null && mp.isPlaying()) mp.stop();
mp.setDataSource(zoo.this,R.raw.gata);
mp.prepare();
mp.start();
break;
Okay, so I've actually been working on something similar for a hobby project I've been working on. After reading through the MediaPlayer documentation for a while, here is the method I've come up with (note that this is with the intention of having only a single sound playing at one time):
First, I created an overridden Application class to hold my global variables -- in this instance, my single MediaPlayer object:
public class GlobalVars extends Application {
private static MediaPlayer mp = new MediaPlayer();
public static MediaPlayer getMediaPlayer() {
return mp;
}
}
This creates one instance of a MediaPlayer once the application begins. It's also static, so it's available without having to instantiate the class.
Now, in my main class (particularly in my onClick method), I retrieve this instance, reset it, set my data source, prepare it for play, and then start it:
MediaPlayer mp = GlobalVars.getMediaPlayer();
//note that in my case, item is an object of mine that
//contains an AssetFileDescriptor, which you can get by
//calling getAssets().openFd("filename.mp3");
AssetFileDescriptor afd = item.getDescriptor();
mp.reset();
//leaving out the try/catch block for conciseness
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.start();
you can use sound manager if you finite no. of sounds to play.http://developer.android.com/reference/android/media/AudioManager.html

Categories