Player short audio in UI thread - android

Is it a good idea to play a short audio within an UI thread? The code is like:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.mymp3);
mMediaPlayer.start();
}
Or, I'd better play the audio in an AsyncTask?
Thanks.

As a thumb of rule running that on the main (that's what it actually means in Android) thread is not a good idea.
There are several reasons, for example, what will happen if tomorrow it will not be a short audio sample? how will the application behave if exactly on the same time an incoming call will arrive...it can take 2-3 seconds (depends on the length of the audio sample) until the user will be able to answer.
The "good practice" for audio playing is using services.

Related

How to reduce Buffer time on streaming app?

I'm Building an android app that is supposed to stream an online radio station from a URL.
I am currently working on a demo and I have gotten a lot of help from online tutorials but I have a problem.
When I click on the NEXT button it's supposed to get it's audio from another URL, which gives it the effect of changing the station, but it takes too much time and most times it doesn't seem to work.
Is there any way I could reduce the time by 95% cause I want it to start almost immediately you click on the next button
CODE FOR THE NEXT BUTTON
b_next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mediaPlayer.stop();
mediaPlayer.reset();
try {
mediaPlayer.setDataSource("http://stream.radioreklama.bg/veronika.opus");
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
});
The problem may not be buffering- there might be some slow startup time on the server side for example.
Either way, if you want to monitor the buffering there is a call back provided with MediaPlayer which will do this - 'OnBufferingUpdateListener.onBufferingUpdate()'.
From the MediaPlayer documentation (https://developer.android.com/reference/android/media/MediaPlayer.html#setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)):
While in the Started state, the internal player engine calls a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback method if a OnBufferingUpdateListener has been registered beforehand via setOnBufferingUpdateListener(OnBufferingUpdateListener). This callback allows applications to keep track of the buffering status while streaming audio/video.
One common technique to speed up switching between streams, across platforms, is to have the next stream prepared in advance.
For your case you would need a second media player which you would initialise and move to the prepared state, and possibly even seek to a point, and then play it as soon as you stop the other one.
For live streams this will be a little more difficult as you can't see to a point in the same way. You could experiment with having the second player playing but with the volume turned down, although this is obviously not very efficient, unless you have some reliable way to predict when the user is about to switch.

Time taken in connecting while audio streaming in android?

I am using simple audio streaming in android app like this:
try {
MediaPlayer media = new MediaPlayer();
media.setAudioStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
media.setDataSource("http://indiespectrum.com:9000");
media.prepare();
media.start();
}
catch(Exception e)
{
//Getting Exception
}
Where I am using four different URL .When I start the radio streaming it takes a while to start playing.Sometimes it takes 5-6 sec and sometimes around 40-45 sec to start playing the radio. I just want to know if I can speed up these time taken .As all of these uses Shoutcast is there anyway I could speed up the connection or it depends on some kind of bitrate or something.Please help?
One way to speed up things a lot is leveraging the UIMain thread and doing the audiostreaming using AsyncTask, wich enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

Gapless Playback with android MediaPlayer

I'm trying to repeatedly play a audio continuously, without any gap. I've tried,
mediaplayer.setLooping(true);
But it gives a gap between repeat time. And tried this,
mediaplayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp)
{
mediaplayer.start();
}
});
It gives a gap also. I've tried with different audio format. But neither way worked for me. Is there any other way in android?
When a playback finishes, the player engine would check if all tracks are completed and once done, it will check for the looping flag. Based on the looping flag, a seek to 0 seconds. As part of the seek, the player engine will read the data from the specific position and start the playback.
The delay may be due to the seek implementation along with the delay introduced by the storage medium like sdcard apart from re-initializing all tracks and restarting them. Hence, there is definite delay by the time the player reverts back to the starting position.
The underlying looping implementation can be found in this function AwesomePlayer::onStreamDone as shown here: http://androidxref.com/4.2.2_r1/xref/frameworks/av/media/libstagefright/AwesomePlayer.cpp#834
EDIT 1:
To implement a true gapless playback, you could also consider the setNextMediaPlayer() feature.
Probably MediaPlayer is re-prefetching the data from server (or even from the device itself), this may take some seconds. Only if the buffering is done, it starts playing again.
If you want to bypass this, you can AFAIK only use a second MediaPlayer which starts buffering the media file shortly before the first one stops playing. Then you can start the second one on OnCompletionListener.

How to use Async task for audio streaming in android

Can we stream an audio file via async task in android. give me an example if u have done.
Alright I've struggled with this myself for quite a while, since everyone always told me "just use prepareAsync() and it will work.
However, you will still need to wait until enough has been buffered before trying to start() otherwise you'll get errors and nothing will happen.
First of, let your music-streamer class implement OnPreparedListener. This will be used to check if enough has been buffered before starting to play.
Next, use this piece of code to start the buffering and set the listener:
mediaPlayer.setDataSource(URL here);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(this);
You have now set your listener to check whether or not enough has been buffered. Only one more step to go
public void onPrepared(MediaPlayer mediaplayer) {
// We now have buffered enough to be able to play
mediaPlayer.start();
}
The song will now be able to start playing without giving errors and all that.
Good luck!
As for the fact you want to play the music and be able to stop it at any time, you will need to use a Service if you plan on being able to stop your music from all activities. There are a few tutorials about that to be found on the internet.
You can use mediaPlayer object.
mediaPlayer.setDataSource("Your datasource");
mediaPlayer.prepareAsync();
The method prepareAsyc: Prepares the player for playback, asynchronously.
For more information see: http://developer.android.com/reference/android/media/MediaPlayer.html
Hope this helps...

AudioHardware pcm playback is going to standby error for playing from SD-card

After reading several similar questions I found that all developers that experience this error see this behaviour when streaming media files from the internet.
I use audio files (MP3) from the SD card and I play them in a Service. I do play them one after each other and at some point MediaPlayer dies with the message shown in the title. It does not throw any error thru the registered OnErrorListener. It's simply dead after the last tune of one of the files. It's always the same file if I use the same file order.
Tracing the app did not show any growth in memory consumption. I even tried to make MediaPlayer static to avoid GC. The last approach was to close MediaPlayer intirely, NULL its static variable and create and restart everything new. This didn't help. If the hardware is gone - it's gone.
I do experience this with a Google Nexus One and I need help. I read a tip to fade out three seconds before end of the files. Is this really a solution and how should I do this?
Many thanks in advance.
well, I think u implemented "onCompletion" event of MediaPlayer,
I think the bug is that android fires onCompletion event while (mediaPlayer.isPlaying) still true
so my idea is to stop media player before playing next mp3
something like this ...
public void onCompletion(MediaPlayer mp) {
if(mp != null && mp.isPlaying()){
Log.d("onCompletion", "mp is playing !!! stop it!!!");
mp.stop();
}
/*
play next item here or prepare or ...
*/
}

Categories

Resources