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...
Related
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.
I am unable to clear myself that why do we need to use prepare() method in Mediaplayer. Why start() independently doesn't work in music players...
The prepare method collects metadata about the file or stream to be played, which may be necessary for proper function of the player itself and related components (like UI). The fact that you can call prepare and prepareAsync separately from calling setDataSource or start is simply a means of allowing the developer control over when and how things happen to suit his/her particular circumstance. Particularly for streaming media, preparation may take a significant amount of time, and so doing things the same way all the time will not be ideal in every situation.
suppose if you want doing some work that can be possible when media player is collecting infoemation then what you do. if start() work for both what happened if media player is collecting information about media. this will be treated as playing and it crashes completely. these are the states and has there works.
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.
I am trying to play multiple audio files, one after the other and am currently using AsyncTasks to prepare and start the mediaPlayer but have failed to find a good way to move on the to next track at the end of the current one. Not every audio file will be played every time, and it's playing is decided by a boolean value.
Any help is much apprecieated.
I guess you have read android-sdk/docs/reference/android/media/MediaPlayer.html , it says:
When the playback reaches the end of stream, the playback completes.
If the looping mode was being set to truewith setLooping(boolean), the
MediaPlayer object shall remain in the Started state. If the looping
mode was set to false , the player engine calls a user supplied
callback method, OnCompletion.onCompletion(), if a
OnCompletionListener is registered beforehand via
setOnCompletionListener(OnCompletionListener). The invoke of the
callback signals that the object is now in the PlaybackCompleted
state. While in the PlaybackCompleted state, calling start() can
restart the playback from the beginning of the audio/video source.
So you may set a new source, prepareAsync then start in completion callback. In this way , you get continuous playback, but it is not seamless.
Doubtful using MediaPlayer for this will work like you want it to. Try this tutorial:
http://www.droidnova.com/creating-sound-effects-in-android-part-1,570.html
If that doesn't work you'll probably have to mix the sounds together yourself them stream that result directly to the hardware using AudioTrack. That's more low level, but it will give you the most control. It just depends on what you are doing if the AudioManager solution will work for you or not. It's definitely the simpler route. But, if you're trying to line up two samples so that when one finishes the next begins, like in a music app, you probably will have to mix and stream that audio yourself.
http://developer.android.com/reference/android/media/AudioTrack.html
Algorithm to mix sound
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 ...
*/
}