MediaPlayer Error (1, -1004) - android

I have searched too much here on stack overflow but I am unable to find any solution of my problem.
I am getting a Media Player Error named 'MEDIA_ERROR_IO' code -1004.
I am stream an audio from server everything works good. song prepared and then starts in onPrepared() method.
Now the problem comes when there is an incoming call and phone starts ringing, and I pauses the song by calling mediaPlayer.pause() from my BroadcastReceiver class.
when the Phone call ends start the audio again by calling mediaPlayer.start()
the audio starts but after 2-3 seconds it stops with an Error that is MediaPlayer error (1, -1004).
Now What should I do?
Any Help is appreciable.
Thank you.

the audio starts but after 2-3 seconds it stops with an Error that is
MediaPlayer error (1, -1004).
First, Lets understand what error (1, -1004) means. -1004 is the error code for IO error. Below reference from MediaPlayer.java source code.
/** File or network related operation errors. */
public static final int MEDIA_ERROR_IO = -1004;
This type of error comes if for some reason, the media player is not able to connect to the server due to network issues. It could be bad internet connectivity at that instance or some network related reason due which the media player was unable to connect to the server. There are some other similar error codes that the media player can throw like time-outs or server died:
/** Some operation takes too long to complete, usually more than 3-5 seconds. */
public static final int MEDIA_ERROR_TIMED_OUT = -110;
/** Media server died.*/
public static final int MEDIA_ERROR_SERVER_DIED = 100;
Now What should I do?
To handle errors generated by media player at run time, you should implement Error Listener. You can handle the error in which ever way as you like for example restart the player.
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch(extra){
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
// Do Something
// eg. reset the media player and restart
break;
case MediaPlayer.MEDIA_ERROR_IO:
// Do Something
// eg. Show dialog to user indicating bad connectivity
// or attempt to restart the player
break;
case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
//Do Something
//eg. Show dialog that there was error in connecting to the server
// or attempt some retries
break;
}
//You must always return true if you want the error listener to work
return true;
}
});

Related

What means the message "internal/external state mismatch corrected" at the MediaPlayer?

I work with a MediaPlayer and set the state of the player often programmatically like for example:
if(mp.isPlaying()) {
mp.pause();
animationPausedMusic();
}
private void animationPausedMusic() {
// Changing button image to play button
btn_play.setBackgroundResource(R.drawable.play);
... // more code
}
But sometimes the logcat gives me the message:
"internal/external state mismatch corrected"
And then the play and pause function is not working anymore.
What does this message mean? And how can I solve it?
After going through the android's native framework for media player I found that in source file mediaplayer.cpp inside function bool MediaPlayer::isPlaying() The developer is checking if the currentState of media player is in STARTED state and yet the media player is not playing any media, so it tries to change the state to PAUSED state so that the state consistency should be maintained for API users.(and here is where he is printing the message "ALOGE("internal/external state mismatch corrected");")
Now If you go through the media player state diagram below:
You would notice that this may happen when the MediaPlayer moved to 'STARTED' state after a call to start() and at this time for some obscure reason has not yet started the playback and you fire a MediaPlayer.isPlaying() method call , The Framework treat this as state inconsistency and moves to 'PAUSED' state and that's why you cannot see anything playing further.
However, if someone has some better understanding please share your thoughts!
I ran into this recently, and like some other questions say, it's this bug (marked obsolete alas)
https://code.google.com/p/android/issues/detail?id=9732
I found this error occurs when playing a MIDI file, but only sometimes. It happens when mp.isPlaying() is called quickly after mp.start()
If you can manage to not call mp.isPlaying() for a little bit, the error doesn't occur. In my case, a 10th of a second or so made the difference between getting the error or not. It's awkward, but it works.
e.g.
//setting a new track
mp.setDataSource(path);
mp.prepare();
mp.start();
//calling mp.isPlaying() here or shortly after starts the problem
//since we know it's playing, we can store that state, or call
updateUiPlaying(); //eg instead of updateUi();
//or just call some code here that takes more time first
updateScaledImages(); //something that might take time
Log.v(TAG, "mp.isPlaying = " + mp.isPlaying()); //now isPlaying() shouldn't cause that error
Also, I put a check in when I pause later.
mp.pause()
if(mp.isPlaying()){
//shouldn't be playing, must be in error
mp.stop();
mp.release();
mp = new MediaPlayer();
//any other initialization here
}
Though the problem doesn't occur if there is a wait before calling isPlaying()
Apparently there is more than one cause of this message. The following solution worked for me. It may or may not work for you. I called the method MediaPlayer.reset() immediately after instantiating the MediaPlayer object:
MediaPlayer mp = new MediaPlayer();
mp.reset();

MediaPlayer onCompletion is not being called accurately

In my app i have created an audio player (only WAV files) using MediaPlayer API.
But the player doesn't give callback to onCompletion Listener everytime. Sometimes it gives callback but not everytime. I am doing some audio processing on wav file , like insertion and overwriting.
Is it because any missing in audio header?
Why it doesn't give callback when the playback is completed?
Make sure that the headers of file is set correctly. If somethings in header is missing callback to the onCompletion may not occur.
If mediaplayer is playing a .wav file, seeking may happen correctly but a jerking will be there . So when the playingback completes there will be a differecnce of 0-1000 ms between total duration of file and onCompletion respectively. So if such a situation comes you should guess that as onColmpletion and do what you wanted. Thats a bit tricky way to get the onCompletion.
I faced the same problem while playing a .wav file with the mediaplayer. This is not a good way to solve this issue, but I tackled the same problem like this when i was having the same situation. Hope this will help you too in some ways.
It seems you have to call setOnCompletionListener AFTER calling start().
Take a look here: https://stackoverflow.com/a/19555480/1860130
Worked for me.
In order to get the onCompletion() function called you should disable looping with a call mediaPlayer.setLooping(false);
Make sure the MediaPlayer is not a local(temporal) variable. Since the local variable will be collected by GC. In that case, the onCompletion will have no chance to be invoked.
You're using the correct Method but have you passed any code in the
"// do some tasks here when playback completes " AREA.
If not then the callback wont make any sense.
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
Toast.makeText(getApplicationContext(),"Playback Completes", Toast.LENGTH_SHORT).show();
}
});
This method will pop a Toast on completion of playback.
Return true to OnErrorListner method on MediaPlayer
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//Invoked when there has been an error during an asynchronous operation
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.e("MediaPlayer Error", "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.e("MediaPlayer Error", "MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.e("MediaPlayer Error", "MEDIA ERROR UNKNOWN " + extra);
break;
}
return true;
}
Try to use a sleep method once recording is completed.
Also use; .prepare() before the placeback occurs , to avoid crashes.

Unclear error when playing a video in a VideoView

I'm trying to play a video (by a uri) in a VideoView and sometimes get the following errors:
E/MediaPlayer(15861): error (1, -2147483648)
D/MediaPlayer(15861): Couldn't open file on client side, trying server side
W/MediaPlayer(15861): mediaplayer went away with unhandled events
I found that the "list" of codes can be found in the following source code:
https://github.com/android/platform_external_opencore/blob/master/pvmi/pvmf/include/pvmf_return_codes.h
(thanks to the thread Complete list of MediaPlayer error codes)
But that does not make things more clear, there's nothing there about -2147483648, and the 1 I get is positive and in this source it says that error codes are negative.
Same thing was reported in this thread: Playing youtube video in a videoview, though he did not ask about what this error means (nor did he get any helping answer).
Anyone has an idea of the meaning of this error?
Thanks.
Edit
I'm trying to show youtube videos, the url of the stream is taken from http://www.youtube.com/get_video_info?&video_id=VIDEO_ID and it's being done asynchronously.
When the result gets back, this is the code I'm using:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
setVideoURI(videoStream);
}
});
This is being executed by a class which extends VideoView.
1 stand for MEDIA_ERROR_UNKNOWN. and -2147483648 is a myth
Refer to the documentation for further details.
This kind of error occurs when trying to play an invalid url. Assuming you are not using third party libraries.

setStreamMute never unmutes

In the documentation, it is said:
The mute command is protected against client process death: if a process with an active mute request on a stream dies, this stream will be unmuted automatically.
The mute requests for a given stream are cumulative: the AudioManager can receive several mute requests from one or more clients and the stream will be unmuted only when the same number of unmute requests are received.
Well, the first paragraph is true; Whenever my process dies, all of the streams I muted are automatically unmuted.
However, no matter how many time I call setStreamMute(someStream, false) it NEVER EVER unmutes.
Last time I tried calling it over 1 million times after muting only ONCE and NOTHING happens!
Just to mention - If i unmute it in the same method I mute it - it stays unmuted. But on the next calls to the same method - it never unmutes.
I am muting in a Broadcast Receiver onReceive method, which I start using an alarm manager. So maybe it because my app was killed during the time between the muting call and the unmuting call? (But my app still stays in the RAM)
Can this problem be because I am not keeping a reference to the AlarmManager (Getting different instances each time?)
Did anyone encounter this problem?
Apperantly, there is a bug in these Android versions; Tested for versions 2.2 and 2.3.3 and the bug exists.
Looks like, if you call setStreamMute on an AudioManager object:
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
am.setStreamMute(...., true);
and you lose your reference, then get a new reference:
am = null;
am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
No matter how many times you call am.setStreamMute(..., false) now, it will never unmutes.
I think ill report this bug now..
Lesson: Keep a static reference to your AudioManager.
#Michell Bak, thanks for giving me the idea to check whether its the Android software bug :) I've been stuck on this thing for way too much time, and I never had the idea to see if its not my fault.
I've never used that API before, but a quick Google search, returned a few results with it not working. It seems to be a bug that's still present in Android 2.3:
http://code.google.com/p/android/issues/detail?id=4235
I solve the problem by putting the audio manager variable in the application
public class myApplication extends Application {
static AudioManager am;
public void onCreate() {
super.onCreate();
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
this.setMute(false);
}
}
Then in my activity class add this function:
private AudioManager getAM() {
return ((elpApplication)getApplication()).am;
}
and here is how I use the getAM();
private void toogleMediaPlayerMute() {
//defaultVolumn = am.getStreamVolume(AudioManager.STREAM_MUSIC);
elpApplication app = getElpApp();
Log.d("appmute", String.valueOf(app.isMute()));
if (!app.isMute()) {
getAM().setStreamVolume(AudioManager.STREAM_MUSIC, 0,
AudioManager.FLAG_PLAY_SOUND);
getAM().setStreamMute(AudioManager.STREAM_MUSIC, true);
ismute = true;
} else {
int maxVolume = getAM().getStreamMaxVolume(AudioManager.STREAM_MUSIC);
Log.d("maxvol", String.valueOf(maxVolume));
getAM().setStreamMute(AudioManager.STREAM_MUSIC, false);
getAM().setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume,
AudioManager.FLAG_SHOW_UI);
ismute = false;
// app.setMute(ismute);
}
app.setMute(ismute);
}
I have been having the same problem w/ newer versions of the API. So, to work [around] this issue, I've implemented a bit of 'old-school' solution. If your design is such that you handle getting the byte stream / sending the byte stream directly - send a byte array filled with zeros if mute is selected:
*
...
byte[] whatToSend = realByteData;
byte [] mutedOutput = new byte[recBuffSize];
Array.setByte( mutedOutput, 0, (byte) 0);
...
if ( muteSet )
whatToSend = mutedOutput;
amountWritten = audioTrack.write(whatToSend, 0, amountRead);
*

VideoView / MediaPlayer Error (1, -18)

I have an application that is built to API level 2.2. This application contains a video that starts playing as soon as it is launched. The video is played inside a VideoView and the actually video file is stored in my internal storage (files directory for my apps package).
Most of the time it starts up just fine. But occasionally I get an error pop - up that says "Sorry, this video cannot be played." and has an Ok button. As soon as I press the ok button the video starts playing correctly. I need to figure out what is causing this error, or at the very least how I can catch whatever error it is and have it try again since it always works perfect after I hit ok. Inside the logs when this error box is shown I see these messages:
ERROR/PVOMXAudDecNode(21215): Ln 2232 OMX_EventError nData1 -2147479547 nData2 0
ERROR/PlayerDriver(21215): Command PLAYER_PREPARE completed with an error or info -18
ERROR/MediaPlayer(9282): message received msg=100, ext1=1, ext2=-18
ERROR/MediaPlayer(9282): error (1, -18)
ERROR/MediaPlayer(9282): callback application
ERROR/MediaPlayer(9282): back from callback
ERROR/MediaPlayer(9282): Error (1,-18)
DEBUG/VideoView(9282): Error: 1,-18
Where can I find a reference as to what exactly error code -18 indicates? And does anyone have any suggestions I could try to prevent it from happening in the first place. I have only observed This error on the Sprint Epic 4g.
Edit: well as far as I can tell no exceptions are getting thrown to me. I assume what is happening is that the video view knows to catch whatever exception is causing and it throws up the pop-up. Inside my log there is no exception stack trace just this reference to error -18.
As for how I am calling prepare. I use this:
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer arg0) {
mVideoView.start();
}
});
and this:
mVideoView.setVideoPath(file.getAbsolutePath());
it calls prepare as part of setVideoPath (I assume it does anyway, but this method is undocumented). which causes onPrepared to get called in my listener.
Edit 2: for now i've just added an onErrorListener like so:
EDIT IMORTANT! this code will infinte error loop on ICS. For ICS devices I took out the setPath call, and returned false instead. It tries again by itself once and it succeeds.
mVideoView.setOnErrorListener(new OnErrorListener(){
#Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
Log.i(myTag, "MP ERROR: "+ arg1 + " - " + arg2);
mVideoView.setVideoPath(file.getAbsolutePath());
return true;
}
});
this catches the error and I can see in my logs that arg2 = -18 when this error happens. I just have it retry and return true so it doesn't throw up the dialog. So far i've never seen it fail twice in a row so this always starts the video correctly and doesn't make infinite loop.
I am still very interested if anyone can tell me exactly what error code -18 indicates though.
How do you catch potential exceptions thrown by prepare()? Do you catch IOException specifically and then retry calling the prepare()?
Try using prepareAsync() instead, which does not block and calls listener when player is ready. Also it does not throw IOException.
If you are running it on Froyo or Gingerbread the problem might be your device is not supporting playback of the file. Lower versions do not support videos encoded with formats other than baseline format. You may use some tools like video info on pc and check if the files are baseline formatted.

Categories

Resources