I am experiencing an odd issue with a video streaming application I am working on. The actual streaming of video/audio is working fine on all of my test devices. However, on seemingly any device 4.0+, when using an RTSP URL, prepare() returns instantly (this causes an issue providing proper feedback to the users while a video is loading and interferes with a few other systems I have in place).
Below is the block of code where I initialize and setup my MediaPlayer, but keep a few things in mind:
My initPlayer method is called from an AsyncTask.
The video does eventually play correctly, but prepare returning instantly creates a lack of feedback to the user during a video load.
No errors of any kind occur during the entire process
start() is called on the MediaPlayer via the onPrepared method in my OnPreparedListener, which obviously becomes an issue when prepare() returns before it is actually ready to be played.
HTTP streams seem to work fine, and on every test device below 4.0 the issue does not occur.
I have been trying to fix this for a ridiculous amount of time, and haven't been able to find anyone else who has ran into this problem. Any ideas would be greatly appreciated.
public void initPlayer() {
//We first need to make sure the MediaPlayer isn't null
if(mMediaPlayer==null){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnPreparedListener(mediaPlayerPreparedListener);
mMediaPlayer.setOnCompletionListener(mediaPlayerCompletionListener);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
//If a video/stream has been chosen while another is already playing
else if(mMediaPlayer.isPlaying()){
mMediaPlayer.reset();
}
//Video is not in full screen mode
second = false;
try {
mMediaPlayer.setDataSource(videoString);
holder = mPreview.getHolder();
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//onPreparedListener
private OnPreparedListener mediaPlayerPreparedListener = new OnPreparedListener(){
public void onPrepared(MediaPlayer mp) {
mp.start();
vidPb.setVisibility(View.INVISIBLE);
}
};
Use mp.prepareAsync() as it is better for streaming media. Using prepare() blocks until MediaPlayer is ready for playback or an IllegalStateException occurs. Also, in android 4 (ICS), blocking on any UI thread is even more strict and may cause an ANR (Activity not responding) dialog to appear.
One final thought, try to avoid using e.printStackTrace(); in android apps.
Instead, use the Log.e("TAG_STRING", e.getMessage(), e); to print errors to the android logging system that you can access from logcat.
All in all, it should looks something like this:
try {
mMediaPlayer.setDataSource(videoString);
holder = mPreview.getHolder();
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
Log.e("TAG_STRING", e.getMessage(), e);
} catch (SecurityException e) {
Log.e("TAG_STRING", e.getMessage(), e);
} catch (IllegalStateException e) {
Log.e("TAG_STRING", e.getMessage(), e);
} catch (IOException e) {
Log.e("TAG_STRING", e.getMessage(), e);
}
Related
I am currently working with FFmpegMediaPlayer in order to make a basic music player given a url. I got the basic functionality to work. On error, I show an error message, else I play the songs.
The problem I am facing is, once the player starts, and I turn off my wifi and phone data, it stops the sound. Once I turn my wifi or phone data back one, I would like the player to continue but it simply stops. I have to stop and play again for it to continue.
Is there a way to have the FFmpegMediaPlayer continue streaming?
This is what I have to initialize the player:
mMediaPlayer = new FFmpegMediaPlayer();
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnSeekCompleteListener(this);
try {
Uri uri = Uri.parse(radio_url);
mMediaPlayer.setDataSource(mMainActivity, uri);
mMediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Then I have a function to handle when Play/Stop button is clicked:
#Override
public void onPlayButtonClicked(Button button) {
if (radioInitialized) {
mAnalytics.onStopButtonClicked();
mMainLayout.loading(false);
mMediaPlayer.pause();
button.setBackground(mMainActivity.getResources().getDrawable(R.drawable.play_button));
radioInitialized = false;
} else {
mAnalytics.onPlayButtonClicked();
mMainLayout.loading(true);
initRadio();
button.setBackground(mMainActivity.getResources().getDrawable(R.drawable.stop_button));
radioInitialized = true;
}
}
Again, the basic functionality works, but I would like for it to continue streaming after wifi is turned back on.
Found a solution.
My main goal was to create a media player like a radio.
I tried MediaPlayer and it works but it tends to stop frequently.
I then tried vitamio and FFmpegMediaPlayer. Vitamio was confusing and FFmpegMediaPlayer doesn't support on streaming error.
I currently got it working with Google's Exo Player. There is a very nice tutorial here: https://codelabs.developers.google.com/codelabs/exoplayer-intro/index.html?index=..%2F..%2Findex#0
I am trying to work with android Equalizer It works if my app has been started , but fails when another app uses equalizer
the app would crash whenever my app tries to access the equalizer library
Is there a way to know if equalizer is available other wise not to start the activity
here is the code I am trying
Equalizer eq = null;
if (eq != null) {
eq.release();
}
try {
eq = new Equalizer(0, 0);
}
catch (IllegalStateException e) {
fail("Equalizer not initialized");
}
catch (IllegalArgumentException e) {
}
catch (UnsupportedOperationException e) {
}
but I still keep getting the error
java.lang.RuntimeException: java.lang.UnsupportedOperationException: Effect library not loaded
you should call release() on your Equalizer object when you're finished with it. You can't have many instance of Equalizer object.
== UPDATE ==
In your catch block, the one causing issue, you could display a Toast and finish current activity :
catch (UnsupportedOperationException e) {
//display a Toast
finish();
}
I am working on application that contacts with media server. So, I have an array that fills with media's URLs. Media type is mp3.
I have a ListView that each row indicates one of array's cell. When clicked event received to each row, It should run setDataSource, prepare and start MediaPlayer. When first time, I clicked on one row, All things are okay and media streams successfully. But when I clicked another while last media is playing, error (1,-114) occurs.
Based on MediaPlayer, I know setDataSource should be run in Idle state of MediaPlayer, So, before setting data source, I invoke reset to move to Idle state.
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(getMusicUrl());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.prepareAsync();
I implement OnErrorListener, The error details is as follows:
What: 1 MEDIA_ERROR_UNKNOWN
Extra: -114 (I haven't found any docs about this error)
Can any one help me to solve this problem?
Could you try calling mediaPlayer.release() when you decide to switch to other song.
my app is playing some audio files, but if the user hits the play button twice, it will play then it will play again (something like that).
I would like the next action to happen JUST when the first execution of the audio file is over.
How can I do that?
Here is my code:
MediaPlayer mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource((endMidia));
mMediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
mMediaPlayer.start();
Any help is appreciatted!
You can make check with MediaPlayer.isPlaying().
There are listeners on MediaPlayer events like OnCompletionListener
http://developer.android.com/reference/android/media/MediaPlayer.html#setOnCompletionListener(android.media.MediaPlayer.OnCompletionListener)
and others
check if condition as shown in below code
MediaPlayer mMediaPlayer = new MediaPlayer();
try {
mMediaPlayer.setDataSource((endMidia));
mMediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
if(!mMediaPlayer.isPlaying()){
mMediaPlayer.start();
}
I am using the MediaRecorder in my app to measure decibel. For this a new MediaRecorder-Object is created once every 10 seconds, it runs for one second during which getMaxAmplitude() is called 10 times and the average is calculated. After this the MediaRecorder object is stopped and deleted.
The Method to start the Recorder looks like this
public boolean start()
{
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null");
try
{
mRecorder.prepare();
}
catch (IllegalStateException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
mRecorder.start();
mRecorder.getMaxAmplitude();
return true;
}
and the Method to stop looks like this
public void stop()
{
//Log.d("SPLService", "stop()");
mRecorder.stop();
mRecorder.reset();
mRecorder.release();
mRecorder=null;
}
This is pretty much the way the tutorial on the Android Website instructed.
The problem arises when I use this app in parallel with other Apps using Media, like the Mediaplayer on Android. Whenever a sound measurement is taken using my App other media Apps stop or even crash, even though their objects should be independent of mine.
I have tried using AudioRecord instead of MediaRecorder but the interference with other apps was the same.
I guess my question would be: how can I avoid such interference?