Android media player fails MP3 with PVMFErrNotSupp

2020-04-26 01:49发布

问题:

I have a downloaded MP3 that I can verify as MP3 by adb pull to my mac or pc and play in its respective media player. However, the error from Android implies that it does not support the format. I think it may be related to the directory location where I am storing the file, but that does not make sense (/data/data/com.myapp/files/file_audio.mp3). This is the code inside an AsyncTask:

    protected String doInBackground(String... params) {

        String filename = params[0];

        try {
            StringBuilder filenameMp3 = new StringBuilder().append(context.getFilesDir());
            filenameMp3.append("/").append(filename);

            Uri uriMp3 = Uri.parse(filenameMp3.toString());
            Log.d(TAG, "Listen to this ringtone! [" + uriMp3.toString() + "]");

            MediaPlayer mp = MediaPlayer.create(context, uriMp3);
            mp.prepare();
            mp.start();
        } catch (IllegalStateException e) {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            e.printStackTrace();
        }

        return null;
    }

Here is the log:

09-07 23:16:09.617 E/MediaPlayerService( 1128): The Default Player is PV_PLAYER***********************
09-07 23:16:09.617 V/PVPlayer( 1128): PVPlayer constructor
09-07 23:16:09.617 V/PVPlayer( 1128): construct PlayerDriver
09-07 23:16:09.617 V/PlayerDriver( 1128): constructor
09-07 23:16:09.627 V/PlayerDriver( 1128): OpenCore hardware module loaded
09-07 23:16:09.627 V/PlayerDriver( 1128): start player thread
09-07 23:16:09.627 V/PlayerDriver( 1128): startPlayerThread
09-07 23:16:09.627 V/PlayerDriver( 1128): InitializeForThread
09-07 23:16:09.627 V/PlayerDriver( 1128): OMX_MasterInit
09-07 23:16:09.647 V/PlayerDriver( 1128): OsclScheduler::Init
09-07 23:16:09.647 V/PlayerDriver( 1128): CreatePlayer
09-07 23:16:09.657 V/PlayerDriver( 1128): AddToScheduler
09-07 23:16:09.657 V/PlayerDriver( 1128): PendForExec
09-07 23:16:09.657 V/PlayerDriver( 1128): OsclActiveScheduler::Current
09-07 23:16:09.657 V/PlayerDriver( 1128): StartScheduler
09-07 23:16:09.657 V/PVPlayer( 1128): send PLAYER_SETUP
09-07 23:16:09.667 V/PlayerDriver( 1128): Send player code: 2
09-07 23:16:09.667 V/PlayerDriver( 1128): CommandCompleted
09-07 23:16:09.667 V/PlayerDriver( 1128): Completed command PLAYER_SETUP status=PVMFSuccess
09-07 23:16:09.667 V/PVPlayer( 1128): setDataSource(/data/data/com.myapp/files/audio.mp3)
09-07 23:16:09.667 V/PVPlayer( 1128): prepareAsync
09-07 23:16:09.667 V/PVPlayer( 1128):   data source = /data/data/com.myapp/files/audio.mp3
09-07 23:16:09.667 V/PlayerDriver( 1128): Send player code: 3
09-07 23:16:09.667 V/PlayerDriver( 1128): handleSetDataSource
09-07 23:16:09.667 V/PlayerDriver( 1128): handleSetDataSource- scanning for extension
09-07 23:16:09.667 V/PlayerDriver( 1128): HandleInformationalEvent: PVMFInfoErrorHandlingStart
09-07 23:16:09.667 V/PlayerDriver( 1128): HandleInformationalEvent: type=26 UNHANDLED
09-07 23:16:09.667 W/MediaPlayer(14630): info/warning (1, 26)
09-07 23:16:09.667 I/MediaPlayer(14630): Info (1,26)
09-07 23:16:09.667 V/PlayerDriver( 1128): CommandCompleted
09-07 23:16:09.667 V/PlayerDriver( 1128): Completed command PLAYER_SET_DATA_SOURCE status=PVMFErrNotSupported
09-07 23:16:09.667 E/PlayerDriver( 1128): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
09-07 23:16:09.667 E/MediaPlayer(14630): error (1, -4)
09-07 23:16:09.677 V/PVPlayer( 1128): run_init s=-2147483648, cancelled=0
09-07 23:16:09.677 V/PlayerDriver( 1128): HandleInformationalEvent: PVMFInfoErrorHandlingComplete
09-07 23:16:09.677 W/PlayerDriver( 1128): PVMFInfoErrorHandlingComplete

Any clues?

回答1:

FileInputStream fis = getBaseContext().openFileInput(filename.toString());
mp = new MediaPlayer();
mp.setOnCompletionListener(onCompleteAudioListener);
mp.setDataSource(fis.getFD());
mp.prepare();
mp.start();

Plus normal check and error handling.



回答2:

It would be good to check whether the file you want to play exists and its length is greater than 0 just to make sure the path is correct:

File file = new File("/data/...../....mp3");

boolean exists = file.exists();

long length = file.length();

Also make sure that your URI starts with file://



回答3:

OK - I got it to work, but not as I hoped I could implement. First, I had to store in the system media folder:

File file = new File("/system/media/audio/ringtones/", filename);

Second, I had to stop, prepare, start the media player. I tried that based on other postings elsewhere on the web.

            if (exists && length > 0) {
                mp = MediaPlayer.create(context, uriMp3);
                mp.stop();
                mp.prepare();
                mp.start();
            } else {
                if (exists) {
                    return String.format("Ringtone has length %d.", length);
                } else {
                    return String.format("Ringtone %s is missing.", uriMp3.toString());
                }
            }