ThumbnailUtils.createVideoThumbnail对于现有的mp4视频返回null [英] ThumbnailUtils.createVideoThumbnail returns null for existing mp4 video

查看:127
本文介绍了ThumbnailUtils.createVideoThumbnail对于现有的mp4视频返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视频,我需要获取它的缩略图.我为此目的使用ThumbnailUtils类,但是它返回null而不是预期的Bitmap.当我调试我的应用程序时,我看到在createVideoThumbnail方法内部的MediaMetadataRetriever.setDataSource会被调用并抛出IllegalArgumentException.在setDataSource内部,我看到以下代码:

I have a video and I need get its thumbnail. I use ThumbnailUtils class for this purpose, but it returns null instead of expected Bitmap. When I debug my app, I see that inside createVideoThumbnail method MediaMetadataRetriever.setDataSource invokes and it throws IllegalArgumentException. Inside setDataSource I see this code:

public void setDataSource(String path) throws IllegalArgumentException {
    if (path == null) {
        throw new IllegalArgumentException();
    }

    try (FileInputStream is = new FileInputStream(path)) {
        FileDescriptor fd = is.getFD();
        setDataSource(fd, 0, 0x7ffffffffffffffL);
    } catch (FileNotFoundException fileEx) {
        throw new IllegalArgumentException(); // and I've found out that method throws IllegalArgimentException inside this catch block
    } catch (IOException ioEx) {
        throw new IllegalArgumentException();
    }
}

我认为这意味着具有给定文件的文件不存在.但是我在文件系统中看到了它,并且可以正常播放.也许还有另一个原因?

I think it means that file with given file doesn't exist. But I see it in file system and it plays fine. Maybe there's another reason?

推荐答案

问题是您要传递给该方法什么以及从中获得什么?

The question is what you're passing to that method and from what you're obtaining it?

下面是我执行此操作的方式,这对我有用,因此它也对您有用.

Below is the way I am doing this, and this works for me, so it should work for you as well.

File videoFile = new File(selectedVideoPath);

Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(videoFile.getAbsolutePath(), MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);

要获取 selectedVideoPath ,您应该使用

To get selectedVideoPath you should use https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java#L257 getPath(Context context, Uri uri) method. Originally it looked like:

public static String getPath(final Context context, final Uri uri) {

    if (DEBUG)
        Log.d(TAG + " File -",
                "Authority: " + uri.getAuthority() +
                        ", Fragment: " + uri.getFragment() +
                        ", Port: " + uri.getPort() +
                        ", Query: " + uri.getQuery() +
                        ", Scheme: " + uri.getScheme() +
                        ", Host: " + uri.getHost() +
                        ", Segments: " + uri.getPathSegments().toString()
                );

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // LocalStorageProvider
        if (isLocalStorageDocument(uri)) {
            // The path is the id
            return DocumentsContract.getDocumentId(uri);
        }
        // ExternalStorageProvider
        else if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

此外,您可以通过调用 videoFile.exists()来添加 videoFile 是否存在的检查.

Additionally you can add checking if videoFile exists by calling videoFile.exists().

此外,如果您要尝试从外部存储读取内容,则可以检查清单文件中是否包含 READ_EXTERNAL_STORAGE 权限,如果要保存文件并尝试获取缩略图,则还应该需要 WRITE_EXTERNAL_STORAGE 权限.

Additionally if you're trying to read from external storage you can check if you have included READ_EXTERNAL_STORAGE permission in Manifest file, and if you're saving file and trying to get it thumbnail you should also need WRITE_EXTERNAL_STORAGE permission.

这篇关于ThumbnailUtils.createVideoThumbnail对于现有的mp4视频返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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