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();
Android-8(Froyo)以上を使用している場合は、 ThumbnailUtils.createVideoThumbnail を使用できます。
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(path,
MediaStore.Images.Thumbnails.MINI_KIND);
Glide を使用すると、非同期でサムネイルが取得されます。
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
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つの方法:
最良の方法は、 Glide を使用することです。バックグラウンドですべての作業を行い、サムネイルをImageViewに直接ロードし、ロード時にアニメーションを表示することもできます。 Uri、byte []および他の多くのソースで動作します。 @Ajjiが述べたように:
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
最も効率的な方法でビットマップが必要な場合は、ThumbnailUtils
を使用します。私の場合、294 912バイトのサイズのビットマップ(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();
追伸:Bitmap
、byte[]
およびreal file .jpeg
形式は、これらの型内の任意の方向に簡単に変換できます。 Uriの場合、多くの場合、ソースファイルへの実際のパスはありませんが、次のように、そこからバイトストリームをいつでも取得できます。
InputStream in = mContext.getContentResolver().openInputStream(uri);
この入力ストリームを使用すると、必要なことを何でも行うことができます。
@Ajjiの答えを参照してください:
Glide.with(context)
.load(videoFilePath) // or URI/path
.into(imgView); //imageview to set thumbnail to
時々黒の画像を返します。この問題は、Glideライブラリの問題で既に言及されています
このコードを使用してください:
BitmapPool bitmapPool = Glide.get(activity).getBitmapPool();
int microSecond = 6000000;// 6th second as an example
VideoBitmapDecoder videoBitmapDecoder = new VideoBitmapDecoder(microSecond);
FileDescriptorBitmapDecoder fileDescriptorBitmapDecoder = new FileDescriptorBitmapDecoder(videoBitmapDecoder, bitmapPool, DecodeFormat.PREFER_ARGB_8888);
Glide.with(activity)
.load(videoPath)
.asBitmap()
.override(50,50)// Example
.videoDecoder(fileDescriptorBitmapDecoder)
.into(holder.ivFirstUpload);
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);
オプションを使用してビットマップをロードし、ビットマップサイズを小さくします。
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;
}
マシュー・ウィリスに対する同様の答えがありますが、反射が追加されています。どうして?科学だから。
/**
*
* @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;
}
このコードスニペットに似たものを試してください。
img.setImageBitmap(ThumbnailUtils.createVideoThumbnail(
Environment.getExternalStorageDirectory().getPath() + "/WhatsApp/Media/WhatsApp Video/"+getItem(position),
MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
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();
}
次のようにサムネイルを直接作成している場合
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'
}
外部ストレージの読み取り許可をマニフェストに追加
<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE"/>