MediaStore.Video.Media.EXTERNAL_CONTENT_URI
的查询仅返回/sdcard/DCIM/100MEDIA
但我希望在我的/sdcard/Android/data/mypackage/files
文件夹中获取视频缩略图。有可能吗?
以下是我的代码的一部分:
ContentResolver cr = getContentResolver();
String[] proj = {
BaseColumns._ID
};
Cursor c = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
if (c.moveToFirst()) {
do
{
int id = c.getInt(0);
Bitmap b = MediaStore.Video.Thumbnails.getThumbnail(cr, id, MediaStore.Video.Thumbnails.MINI_KIND, null);
Log.d("*****My Thumbnail*****", "onCreate bitmap " + b);
ImageView iv = (ImageView) findViewById(R.id.img_thumbnail);
iv.setImageBitmap(b);
}
while( c.moveToNext() );
}
c.close();
答案 0 :(得分:114)
如果您使用的是android-8(Froyo)或以上版本,则可以使用ThumbnailUtils.createVideoThumbnail:
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
答案 1 :(得分:19)
使用Glide它将在异步中获取缩略图。
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
答案 2 :(得分:4)
您可以使用FFmpegMediaMetadataRetriever并忘记反思:
/**
*
* @param path
* the path to the Video
* @return a thumbnail of the video or null if retrieving the thumbnail failed.
*/
public static Bitmap getVideoThumbnail(String path) {
Bitmap bitmap = null;
FFmpegMediaMetadataRetriever fmmr = new FFmpegMediaMetadataRetriever();
try {
fmmr.setDataSource(path);
final byte[] data = fmmr.getEmbeddedPicture();
if (data != null) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
if (bitmap == null) {
bitmap = fmmr.getFrameAtTime();
}
} catch (Exception e) {
bitmap = null;
} finally {
fmmr.release();
}
return bitmap;
}
答案 3 :(得分:2)
从视频获取缩略图的3种方法:
最好的方法是使用Glide。它将在后台完成所有工作,将缩略图直接加载到ImageView中,甚至可以在加载时显示动画。它可以与Uri,byte []和许多其他源一起使用。 正如@Ajji提到的:
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
如果仅以最有效的方式需要位图,请使用ThumbnailUtils
。
就我而言,它产生的位图大小为294912字节(使用Nexus5X相机拍摄的视频-1280x720),其质量与下一种方法相同。用90压缩为JPEG后,它将生成一个约30Kb的jpeg文件。
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
最后一种方法是使用MediaMetadataRetriever
。但是在我的情况下,它生成的位图的大小是ThumbnailUtils
的6倍(质量相同)。因此,将其视为最后的选择。
MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
mMMR.setDataSource(mContext, mAttachment.getUri());
bmp = mMMR.getFrameAtTime();
P.S .:请不要忘记,Bitmap
,byte[]
和real file .jpeg
格式的图像可以在这些类型的任何方向上轻松转换。如果是Uri,则通常没有到源文件的真实路径,但是您始终可以从中获取字节流,如下所示:
InputStream in = mContext.getContentResolver().openInputStream(uri);
并且使用此输入流,您可以做任何您想做的事。
答案 4 :(得分:1)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmapThumb = MediaStore.Video.Thumbnails.getThumbnail(mActivity.getContentResolver(),
Long.parseLong(video_id),
Images.Thumbnails.MINI_KIND,
options);
使用选项加载减少位图大小的位图..
答案 5 :(得分:1)
从 VIDEO_ID 获取视频缩略图:
public static Drawable getVideoThumbnail(Context context, int videoID) {
try {
String[] projection = {
MediaStore.Video.Thumbnails.DATA,
};
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(
MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
projection,
MediaStore.Video.Thumbnails.VIDEO_ID + "=?",
new String[] { String.valueOf(videoID) },
null);
cursor.moveToFirst();
return Drawable.createFromPath(cursor.getString(0));
} catch (Exception e) {
}
return null;
}
答案 6 :(得分:1)
请参阅@Ajji的回答:
cannot fine module 'moment'
它有时会返回黑色图像,这个问题已在Glide图书馆的问题中提及
使用此代码:
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
答案 7 :(得分:0)
这是马修威利斯的一个类似的答案,但增加了反思。为什么?因为科学。
/**
*
* @param path
* the path to the Video
* @return a thumbnail of the video or null if retrieving the thumbnail failed.
*/
public static Bitmap getVidioThumbnail(String path) {
Bitmap bitmap = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
bitmap = ThumbnailUtils.createVideoThumbnail(path, Thumbnails.MICRO_KIND);
if (bitmap != null) {
return bitmap;
}
}
// MediaMetadataRetriever is available on API Level 8 but is hidden until API Level 10
Class<?> clazz = null;
Object instance = null;
try {
clazz = Class.forName("android.media.MediaMetadataRetriever");
instance = clazz.newInstance();
final Method method = clazz.getMethod("setDataSource", String.class);
method.invoke(instance, path);
// The method name changes between API Level 9 and 10.
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD) {
bitmap = (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
} else {
final byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
if (data != null) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
if (bitmap == null) {
bitmap = (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
}
}
} catch (Exception e) {
bitmap = null;
} finally {
try {
if (instance != null) {
clazz.getMethod("release").invoke(instance);
}
} catch (final Exception ignored) {
}
}
return bitmap;
}
答案 8 :(得分:0)
如果您直接创建缩略图,如下所示
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
如果您正在为大型视频集(针对大量视频)创建缩略图,则此方法存在问题。应用程序将冻结,直到所有缩略图都被加载,因为所有进程都在主线程中执行。
使用SuziLoader
此加载程序将加载视频的缩略图,这些视频本地存储在后台文件系统中。
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video.mp4";
ImageView mThumbnail = (ImageView) findViewById(R.id.thumbnail);
SuziLoader loader = new SuziLoader(); //Create it for once
loader.with(MainActivity.this) //Context
.load(path) //Video path
.into(mThumbnail) // imageview to load the thumbnail
.type("mini") // mini or micro
.show(); // to show the thumbnail
要获得此依赖关系,请使用以下步骤
第1步。将JitPack存储库添加到构建文件中 将其添加到存储库末尾的根build.gradle中:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
第2步。添加依赖项
dependencies {
compile 'com.github.sushinpv:SuziVideoThumbnailLoader:0.1.0'
}
添加READ外部存储清单
中的权限<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
答案 9 :(得分:0)
尝试类似于此代码段的内容:
img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
答案 10 :(得分:0)
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA };
Cursor c = getContentResolver().query(uri, projection, null, null, null);
int vidsCount = 0;
if (c != null) {
vidsCount = c.getCount();
while (c.moveToNext()) {
String path = c.getString(0);
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
}
c.close();
}
答案 11 :(得分:0)
您可以将此方法与任何Uri
一起使用:
public static Bitmap getVideoFrame(Uri uri, Context context) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(context, uri);
return retriever.getFrameAtTime();
}