MediaMetadataRetriever.setDataSource(本机方法)导致RuntimeException:status = 0xFFFFFFEA [英] MediaMetadataRetriever.setDataSource(Native Method) causes RuntimeException: status = 0xFFFFFFEA

查看:485
本文介绍了MediaMetadataRetriever.setDataSource(本机方法)导致RuntimeException:status = 0xFFFFFFEA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ReactNative 构建媒体播放器.为了完成这样的应用程序,我必须导出我构建的用于检索音乐元数据(如专辑,艺术家等)以及文件路径的模块.

I'm building a media player using ReactNative. In order to accomplish such app I had to export a module I built for retrieving music metadata like album, artist, etc as well as file path.

上面的代码使用 jdk1.8.0_112 可以完美地工作,但是由于我更新为 jdk1.8.0_144 ,所以它停止了工作.

The code above was working perfectly using jdk1.8.0_112, but since I updated to jdk1.8.0_144 It stopped working.

在此示例中,我没有检查不为null,不为空,长度> 0等,但是我确实是在原始示例中进行了检查.

In this example, I'm not checking for not null, not empty, length > 0, etc, But I really do in the original one.

try {
    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
    mmr.setDataSource("Path to the file"); // /storage/337C-1C15/Music/Edguy/Speedhoven.mp3
} catch (RuntimeException ex) {
    // java.lang.RuntimeException: setDataSource failed: status = 0xFFFFFFEA
}

我面临两个问题.一方面,我不是一个出色的Android开发人员,所以要获得一些线索是一项艰巨的任务.另一方面,该错误确实提供了很好的描述.

I'm facing two problems. On one hand, I'm not a great Android dev so getting some clues is such hard task. On the other hand, the error does provide a good description.

以防万一某些人有更好的方法来完成我尝试的操作,我将整个代码留在这里:

Just in case some of you had a better way to accomplish what I tried, I left here the whole code:

@ReactMethod
public void getAll(Callback errorCallback, Callback successCallback){

    ContentResolver musicResolver = this.getCurrentActivity().getContentResolver();
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);

    if (musicCursor != null && musicCursor.moveToFirst()) {

        WritableArray jsonArray = new WritableNativeArray();
        MediaMetadataRetriever mmr = new MediaMetadataRetriever();
        WritableMap items = new WritableNativeMap();

        int titleColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
        int idColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
        int artistColumn = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);

        try {
            do {
                items = new WritableNativeMap();
                byte[] art;

                long thisId = musicCursor.getLong(idColumn);
                String thisPath = musicCursor.getString(musicCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                String thisTitle = musicCursor.getString(titleColumn);
                String thisArtist = musicCursor.getString(artistColumn);
                String duration = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));


                if(thisPath != null && thisPath != "" && thisPath.endsWith(".mp3")) {

                    mmr.setDataSource(thisPath);

                    String album = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
                    String artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
                    String title = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
                    String genre = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
                    String encoded = "";
                    String encodedImage = "";
                    art = mmr.getEmbeddedPicture();

                    if (album == null) {
                        album = thisArtist;
                    }

                    if (artist == null) {
                        artist = thisArtist;
                    }

                    if (title == null) {
                        title = thisTitle;
                    }

                    if (art != null) {
                        Bitmap songImage = BitmapFactory.decodeByteArray(art, 0, art.length);
                        if(songImage != null){
                            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                            songImage.compress(Bitmap.CompressFormat.JPEG, 60, byteArrayOutputStream);
                            byte[] byteArray = byteArrayOutputStream.toByteArray();
                            encodedImage = Base64.encodeToString(byteArray, Base64.DEFAULT);
                            String pathtoImg = "";
                            byte[] imageByte = Base64.decode(encodedImage, Base64.DEFAULT);
                            try {
                                pathtoImg = Environment.getExternalStorageDirectory() + "/" + thisId + ".jpg";
                                File filePath = new File(pathtoImg);
                                FileOutputStream fos = new FileOutputStream(filePath, true);
                                encoded = pathtoImg;
                                fos.write(imageByte);
                                fos.flush();
                                fos.close();
                            } catch (FileNotFoundException fnfe) {
                                errorCallback.invoke(fnfe.getMessage());
                            } catch (IOException ioe) {
                                errorCallback.invoke(ioe.getMessage());
                            }
                        }
                    }

                    String str = String.valueOf(thisId);
                    items.putString("id", str);
                    items.putString("album", album);
                    items.putString("artist", artist);
                    items.putString("title", title);
                    items.putString("genre", genre);

                    if (encoded == "") {
                        items.putString("cover", "");
                    } else {
                        items.putString("cover", "file://" + encoded);
                    }

                    items.putString("duration", duration);
                    items.putString("path", thisPath);
                    jsonArray.pushMap(items);
                }
            } while (musicCursor.moveToNext());

            successCallback.invoke(jsonArray);
            mmr.release();
        } catch (RuntimeException e) {
            errorCallback.invoke(e.toString());
            mmr.release();
        } catch (Exception e) {
            errorCallback.invoke(e.getMessage());
            mmr.release();
        }
    }
}

当然,我已经看过:

  • This post
  • This post
  • This post

推荐答案

经过大量调试和研究,我发现了问题所在.

After debugging and researching a lot I found the problem.

似乎文件出现问题时,mmr.setDataSource("path")返回RuntimeException. 这一点特别重要,因为即使文件存在,其元数据也无法检索.

It seems that mmr.setDataSource("path") returns a RuntimeException when something is wrong with the file. This is particularly important since even when the file exists its metadata cannot be retrieved.

解决方案是像这样将MediaMetadataRetriever用作try/catch:

The solution was to use the MediaMetadataRetriever into a try/catch like this:

while(cursor.moveNext()){
  try {
    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
    mmr.setDataSource("Path to the file"); // /storage/337C 1C15/Music/Edguy/Speedhoven.mp3
  } catch (RuntimeException ex) {
    // something went wrong with the file, ignore it and continue
  }
}

这篇关于MediaMetadataRetriever.setDataSource(本机方法)导致RuntimeException:status = 0xFFFFFFEA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆