0

I am learning about mediaplayer in android.

I wanted some simple and easy to understand code example of MediaPlayer.setDataSource().

ADITYA DIXIT
  • 141
  • 1
  • 11

2 Answers2

0

Well, for more deep understanding of MediaPlayer that's better to read official documentation https://developer.android.com/reference/android/media/MediaPlayer#setDataSource(android.content.res.AssetFileDescriptor). But for basic comprehension here is the code example.

MediaPlayer mp = new MediaPlayer();

        // Here you may set which stream to use either MEDIA or ALARM etc.
        mp.setAudioStreamType(AudioManager.STREAM_ALARM);
        try {
            if (isAnyActiveSongExist){
                // Here you may set dataSource as path of the file
                mp.setDataSource(firstPrioritySongEntityPath);
            }
            else{
                // Here you may set dataSource using Uri
                mp.setDataSource(context, Settings.System.DEFAULT_RINGTONE_URI);
            }

            mp.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mp.start();

setDataSource() defines which file should be used by your MediaPlayer for playing.

0

First of all, code never been simple and easy until you'll not go through it. Check this link click here, I think you'll have your answer from here

About setDataSource(String) call

After seeing your comment, it looks like you exactly want setDataSource(string) to be used for your purpose. I don't understand why. But, what I assume is, for some reason you are trying to avoid using "context". If that is not the case then the above two solutions should work perfectly for you or if you are trying to avoid context, I'm afraid that is not possible with the function with signature setDataSource(String) call. The reason is as below,

MediaPlayer setDataSource() function has these below options out of which you are only interested in setDataSource(String),

enter image description here

public void setDataSource(String path)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        setDataSource(path, null, null);
    }

and if you check setDataSource(String path, String[] keys, String[] values) code, you will see the below condition filtering the path based on its scheme, particularly if it is "file" scheme it calls setDataSource(FileDescriptor) or if scheme is non "file", it calls native JNI media function.

{
        final Uri uri = Uri.parse(path);
        final String scheme = uri.getScheme();
        if ("file".equals(scheme)) {
            path = uri.getPath();
        } else if (scheme != null) {
            // handle non-file sources
            nativeSetDataSource(
                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
                path,
                keys,
                values);
            return;
        }
        final File file = new File(path);
        if (file.exists()) {
            FileInputStream is = new FileInputStream(file);
            FileDescriptor fd = is.getFD();
            setDataSource(fd);
            is.close();
        } else {
            throw new IOException("setDataSource failed.");
        }
}

In the above code, your resource file URI scheme will not be null (android.resource://) and setDataSource(String) will try to use native JNI function nativeSetDataSource() thinking that your path is http/https/rtsp and obviously that call will fail as well without throwing any exception. Thats why your call to setDataSource(String) escapes without an exception and gets to prepare() call with the following exception.

Prepare failed.: status=0x1

So setDataSource(String) override cannot handle your resource file. You need to choose another override for that.

On the other side, check setDataSource(Context context, Uri uri, Map headers) which is used by setDataSource(Context context, Uri uri), it uses AssetFileDescriptor, ContentResolver from your context and openAssetFileDescriptor to open the URI which gets success as openAssetFileDescriptor() can open your resource file and finally the resultant fd is used to call setDataSource(FileDescriptor) override.

 AssetFileDescriptor fd = null;
    try {
        ContentResolver resolver = context.getContentResolver();
        fd = resolver.openAssetFileDescriptor(uri, "r");
        //  :
        //  :
        //  :
        if (fd.getDeclaredLength() < 0) {
                setDataSource(fd.getFileDescriptor());
            } else {
                setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength());
            }

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.

Refer to the complete source code for more understanding here: Android MediaPlayer

Md Enayat
  • 147
  • 1
  • 12