Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaPlayer setDataSource need best practice advice

After reading "Media Playback" and "MediaPlayer" android documentations I'm still confused and need experienced advice about setDataSource overloaded method.

I am using MediaPlayer in a Service component in my Project that is going to be a foregroundService while playing music. I have my music file(.mp3) in res/raw folder of my apk. To start playing, I know I have to prepare the MediaPlayer object. Because Services in android applications by default uses single process and main thread, I don't want my users get ANR while MediaPlayer prepares itself(think if media file in raw folder has a big size). Then I use prepareAsync instead of prepare(Sync). So I can not use:

mp = MediaPlayer.create(context, R.raw.myfile);

Because this already calls prepare() internally but not prepareAsync(). So basically i have two options(two from four):

Uri myUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.myfile);
mp.setDataSource(context, myUri);

or

AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.myfile);
mp.setDataSource(fd.getFileDescriptor());
afd.close();

after using one of them I can simple use:

mp.prepareAsync();

And finally my questions arise that "including these different methods, which one is the best option? Are there any benefits one over the other? Do i missing something?"

like image 933
Fredrick Gauss Avatar asked Sep 24 '13 09:09

Fredrick Gauss


People also ask

Which method is used to bring the media player to prepared state?

So instead of calling MediaPlayer directly, MediaPlayerWrapper is used, which internally updates StateMachine and exposes getState() method.

What is MediaPlayer release?

android.media.MediaPlayer. MediaPlayer class can be used to control playback of audio/video files and streams. MediaPlayer is not thread-safe. Creation of and all access to player instances should be on the same thread. If registering callbacks, the thread must have a Looper.

What method is used to call media?

After that, you have to prepare it using either the prepare() or prepareAsync() method. When the MediaPlayer is done preparing, it enters the Prepared state, which means you can call start() to make it play the media.

How to use resource file on setdatasource(string) of mediaplayer?

Using resource file on setDataSource (String) of MediaPlayer is not possible as it cannot accept resource file path. Please note that, I said "resource file path" starts with the scheme android.resource// which is actually a jar location (within your apk), not a physical location.

Can I use setdatasource(string) override to play an MP3 file?

To conclude, you cannot use setDataSource (String) override as is to use your resource mp3 file. Instead, if you want use string to play your resource file you can use either MediaPlayer.create () static function with getIdentifier () as given above or setDataSource (context,uri) as given in Update#1.

How to play raw resources in mediaplayer?

The resource ID must be converted to an AssetFileDescriptor because this is what MediaPlayer uses to play raw resources. The null check ensures the resource exists. Calling reset () ensures the player is in the Initialized state. This works no matter what state the player is in. Set the data source for the player.

Is mediaplayer too simple to use?

MediaPlayer seems to be deceptively simple to use, but complexity lives just below the surface. For example, it can be tempting to write something like this: This works fine the first and probably the second, third, or even more times. However, each new MediaPlayer consumes system resources, such as memory and, codecs.


1 Answers

There aren't any real benefits to the various ways of calling create or setDataSource. The static create methods don't do much more than call setDataSource and prepare. The various setDataSource methods call each other internally. Eventually they boil down to two possible native calls, one with a string describing a remote URI and another with a local file descriptor. There may be a very slight performance advantage to creating the file descriptor yourself, but it will not be appreciable in context.

For local file playback, as you are demonstrating in your code, simply calling prepare (or the static create methods) isn't a bad practice at all. The underlying player should have no problem determining the relevant metadata and returning quickly no matter the size of the file. The prepareAsync method is more useful for network streams, where any number of situations might cause some unexpected delay. If you are designing a general purpose player, then using the prepareAsync method would be the way to go, but if you are simply playing raw assets it shouldn't make any difference. The variety of methods provided is simply a matter of convenience (take note of the javadoc for create).

like image 131
Dave Avatar answered Sep 27 '22 21:09

Dave