ThumbnailUtils.createVideoThumbnail对于现有的mp4视频返回null [英] ThumbnailUtils.createVideoThumbnail returns null for existing mp4 video
问题描述
我有一个视频,我需要获取它的缩略图.我为此目的使用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);
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屋!