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.
Related
I have an app that plays an song displaying its lyrics on the screen.
Two situations:
When the song is loaded from a local mp3 file.
When the song is loaded from remote location via internet
My understanding is that Android Service comes to rescue when the song is streamed from remote location via internet. Android Service helps here because of the i/o overheads involved. In the first case, where the song is played form local location, services is perhaps an overkill. I can simply play the music loading it in the activity and use MediaPlayer API to play it.
Is this understanding correct? Am I missing anything?
Update: The song size is over 10MB. So when you stream it via a slow internet over phone there might be some buffering and stuff to be accommodated for better user experience.
Thanks in advance.
There are different Services for different use cases. For a Media Player it depends if you want to have the playback continuously playing in the back- or foreground.
So both cases are applicable for a Media Player Service. But the Android Developer Guide Media Player Service outshines my answer
Using a Service with MediaPlayer
If you want your media to play in the background even when your application is not onscreen—that is, you want it to continue playing while the user is interacting with other applications—then you must start a Service and control the MediaPlayer instance from there. You should be careful about this setup, because the user and the system have expectations about how an application running a background service should interact with the rest of the system. If your application does not fulfil those expectations, the user may have a bad experience. This section describes the main issues that you should be aware of and offers suggestions about how to approach them
Your second case is more a question about networking and in this case you could use a IntentService to download the .mp3 and pass it to the MediaPlayer.
I am using a MediaPlayer to stream audio from a URL.
According to the documentation, calling the MediaPlayer pause followed by a play will resume from the point where it was paused.
I am wondering how this works with a live audio stream. When I call pause is the MediaPlayer creating some sort of buffer of all the incoming data, and storing it until I call play again?
If this is indeed the case, is there a max size on this buffer? I am mainly concerned about a user pausing the MediaPlayer and it using a lot of memory while it stores incoming audio data.
As, I understand you are using Mediaplayer for streaming audio from a URL.. something like radio channels. In this process, you are using buffers. So, the behaviour you are getting is quite obvious. When you pause, your data will continue to store and on resuming the stream, it will start from the point it was paused.
But streaming should not behave in this manner unlike stored audio which start from the point it was paused. Streaming audio should always start from the live streaming at that point. So, onPause, you should free the buffers. When the user resumes again, you can restart the stream the way you did it first time. This is how the behavior should be.
If you check out, normal radio streaming is implemented in most of the radio streaming apps.
I have an application in android which uses many mediaplayers from a service.
Seeking a way that pressing a button, stop the audio.
The problem is that I can not know the name of the media player is playing when I press the button.
Is there any way to stop all mediaplayers? or to detect the name of the mediaplayer is playing and stop it?
I appreciate any help
Thanks and regards
At most, you need two MediaPlayer objects. While one is playing, call prepare or prepareAsync on the other. After the 2nd finishes preparation (in OnPreparedListener if using async), call setNextMediaPlayer on the MediaPlayer object that is currently playing. If the current one has finished before preparation completed just go ahead and call start instead.
Be sure to call release in the OnCompletionListener for each player, and if there are more files to play simply call setDataSource and prepare (or prepareAsync) for the next media. You can continue this pattern indefinitely without using extraneous resources, and the playback should switch as seamlessly as Android is able to make it.
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
I have a simple app, which plays a short sound repeatedly, by invoking the play() method on the audio element in JavaScript. It works well on desktop browsers, ipads, iphones, etc. On a mobile device running Android 2.3.3, the first time I play the sound, I hear it immediately after invoking the play() method, but on subsequent invocations, there is a noticeable and variable delay.
I have done some sleuthing and found that the device is fetching the audio file from the server each time the play() method is invoked. I can invoke the load() method on the audio element to re-load it after each play, thus queueing it up for the next play, but there are a number of problems with that band-aid. I'd really like to make the browser just keep the audio element loaded permanently, instead of unloading it as soon as it finishes playing. Does anyone know if that's possible?
EDIT: I've done a little more investigating, and I've found that after playing the sound, the audio element's readystate remains at HAVE_ENOUGH_DATA, even though the browser won't play that sound again without re-fetching it from the server. I believe this is a bug. I'd hoped to use the readystate to detect browsers that unload after playing, and only explicitly load if necessary, but that's not going to work.
The more experiments I do, the more rough edges I find in Android 2.3.3's implementation of the HTML5 audio tag. There's a lot broken there, at least on the Droid X phone I'm using for testing.
The best I have come up with so far is the band-aid alluded to in my original question: as soon as an invocation of play() completes, invoke the load() method, to prepare for the next play():
if (navigator.userAgent.toLowerCase().indexOf("android") > -1)
audElt.addEventListener('ended', function () {
var t = setTimeout(function () { audElt.load(); }, 1000);
}, false);
I had to restrict the work-around to Android user agents, because simply invoking the load() method creates problems on Chrome and generates unnecessary trips to the server on non-Android systems.
I had to add a 1-sec delay, because if I simply invoked load() from the "ended" handler, it interrupted the playback, which, apparently, hadn't really "ended" yet....
Of course, it's still fetching the sound from the server repeatedly, so if you try to play the sound multiple times in rapid succession, things go south quickly.
best solution i've found. Another options is to just use the video tag but there are some problems with that as well. Nothing seems to work good enough to implement.
luckily im using phone gap so I'll give their audio methods a shot.
You can bind on updatetime to pause() the playback a second before reaching the end of the audio and rewind before playing it again. Android will not flush the audio then.