Get Video Thumbnail from Uri - android

I want to select a video from my Gallery. It's working fine. But now I want to display a Bitmap, as a thumbnail.I tried this code and it's not working, it always says: NullPointerException
Bitmap bitmap2 = ThumbnailUtils.createVideoThumbnail(uri.getPath, MediaStore.Video.Thumbnails.MICRO_KIND);
This is all in an onActivityResult().
How can I get the Bitmap from the video Uri??
Thanks for your help

In the latest API 24, you may face some issues if you stick with an approach in the accepted answer.
for example in this line int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); sometimes I got W/System.err: java.lang.IllegalArgumentException: column '_data' does not exist error message.
also in the latest API, you may get SecurityException if you deal with widgets or shared content. Keep that in mind.
As for the video thumbnail from Uri - I use an approach which utilizes MediaMetadataRetriever, thus you don't need to get String filePath:
MediaMetadataRetriever mMMR = new MediaMetadataRetriever();
mMMR.setDataSource(context, videoUri);
bmp = mMMR.getFrameAtTime();
Hope this helps

in onActivityResult
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND);
Edit
Kotlin version
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = context.contentResolver.query(uri, filePathColumn, null, null, null)
cursor.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
val bitmap = ThumbnailUtils.createVideoThumbnail(picturePath, MediaStore.Video.Thumbnails.MICRO_KIND)

Try this one:
Bitmap bitmap2 = ThumbnailUtils.createVideoThumbnail( uri.getPath() , MediaStore.Images.Thumbnails.MINI_KIND );

For API 27, for document URI (1000 is microseconds)
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource( context, doc_uri );
Bitmap bm = mmr.getScaledFrameAtTime( 1000, MediaMetadataRetriever.OPTION_NEXT_SYNC, 128, 128 );

This works for me:
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MINI_KIND);
Using ThumbnailUtils, you can create thumbnail of two types.
MediaStore.Images.Thumbnails.MICRO_KIND - type will generate thumbnail of size 96 x 96.
MediaStore.Images.Thumbnails.MINI_KIND - type will generate thumbnail of size 512 x 384.

createVideoThumbnail() needs the file path, not the content uri.
The file path requires external read permissions.
If you're getting null responses, it may be from using the content uri (though the assumption in ThumbnailsUtils.java is of a corrupt video file). When I fixed that, then I was getting permissions errors.
I was able to get the file path from the content uri using the video's ID like this:
val selection = MediaStore.Video.Media._ID + " = $id"
val cursor =
this.contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null,
selection, null, null)
And then continue on with the cursor as in the other answers in SO.
Docs for contentResolver.query()

Cursor c = MediaStore.Video.query(cr,uri, new String[]{
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.DATA});
if (c!=null){
c.moveToFirst();
int id = Integer.valueOf( c.getString(0) );
c.close();
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 1;
try {
return MediaStore.Video.Thumbnails.getThumbnail(cr, id, MediaStore.Video.Thumbnails.MINI_KIND, options);
}catch (java.lang.SecurityException ex){
ex.printStackTrace();
//TODO: add create ThumbnailUtils.createVideoThumbnail
return null;
}
}

CancellationSignal ca = new CancellationSignal();
var vthumb = ThumbnailUtils.createVideoThumbnail(new File(value),new Size(120,120), ca);

Related

Getting individual image of mp3 file is too slow

I am trying to get the image of mp3 file on my phone. I've been struggling a few days and now I know;
Firstly, I use a content provider with this code
` Uri allSongsUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ALBUM_KEY,
MediaStore.Audio.Media.DATE_MODIFIED
};
String sortOrder = MediaStore.Video.Media.DATE_MODIFIED + " DESC";
And I create my cursor like this;
Cursor cursor = ctx.getContentResolver().query(allSongsUri, projection, null, null, sortOrder);
In there I have all my mp3 files. That's ok. Now I want to get their's cover image.
If I use MediaMetadataRetriver's getEmbeddedPicture method like this
mediaMetadataRetriever.setDataSource(localeMusic.getPath());
localeMusic.setImage(mediaMetadataRetriever.getEmbeddedPicture());
it took about 6-7 seconds with nearly 40-50 file. Because getEmbeddedPicture() is too slow!.
Also tried to get album_id and query another cursor to MediaStore.Audio.Albums and I saw all album id is the same because all of them is the same folder. I don't want to show their Album image. I want to show the file's cover image.
I tried this like here But in there, we are getting file's albums image. That is not I ask.
Where can I find the file's image path? Where can the MetadataRetriever class get it with getEmbeddedPicture? Where is that embedded picture?
Thanks. Best regards
mediaMetadataRetriever.getEmbeddedPicture() is a native method and every native method call has a price because JNI calls takes time. So, if you iterate such calls, you may lost a lot of time. You may try to call this method asynchronously on demand and cache the result. Try to combine with glide
This will solve two of your problem at the same time, glide calls is naturally asnyc, so you don't need to implement an AsyncTask class also it caches your images.
This is the basic glide usage:
Glide.with(context).load(mediaMetadataRetriever.getEmbeddedPicture());
I encourage you to read glide documents. It has lots of other features.
Hope this helps.
You can get the album art as mentioned here
https://stackoverflow.com/a/17574629/3825975
Basically,
Cursor cursor = getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[] {MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Albums._ID+ "=?",
new String[] {String.valueOf(albumId)},
null);
if (cursor.moveToFirst()) {
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART));
// do whatever you need to do
}
But to get individual song art, this is how I remember doing it. Hope it helps.
float ht_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
float wt_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
Bitmap artwork, bitmap2 = null;
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
byte[] rawArt;
BitmapFactory.Options bfo = new BitmapFactory.Options();
try {
mmr.setDataSource(songUri); //songUri is the uri of the song. You need to extract this from the song id
rawArt = mmr.getEmbeddedPicture();
if (rawArt != null)
bitmap2 = BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
if (bitmap2 == null)
bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.def_icon);
artwork = Bitmap.createScaledBitmap(bitmap2, (int) ht_px, (int) wt_px, true); //This is the bitmap you need
} catch (Exception e) {
//Exception handling
}
}

Bitmap from media android is returned null all of a sudden

this used to work and now not anymore. Don't get why.
I want to get reference to a photo from my android phone:
Cursor cursor = getActivity().getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgDecodableString = cursor.getString(columnIndex);
cursor.close();
BitmapFactory.Options options = new BitmapFactory.Options ();
options.inSampleSize = 4;
// case 1
final String fname = new File(getActivity().getFilesDir(), imgDecodableString).getAbsolutePath();
Bitmap fBitmap = decodeFile(new File(getActivity().getFilesDir(), imgDecodableString));
// case 2
Bitmap tempBitmap = BitmapFactory.decodeFile(imgDecodableString, options);
And while debugging:
fname: /data/data/com.test.app/files/storage/emulated/0/Download/A-small-kitten-in-a-Christmas-cap-HD-wallpaper_960x800-1.jpg
imgDecodableString: /storage/emulated/0/Download/A-small-kitten-in-a-Christmas-cap-HD-wallpaper_960x800-1.jpg
Bitmap object is always null...
I need a new pair of fresh eyes on this, please. Thank you.
My bad, i deleted the storage permission. Was looking in the wrong place. So the above code works in addition with
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Thanks.

How to get a File from a URI?

I select an image from the image gallery in my app. In the onActivityResult it returns an Intent object and I execute the getData() method on it. I get the image URI back. I am now trying to convert that in to a File so I can send it to AWS S3.
This is what I have been trying but it just returns null:
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
I also try
File file = new File(imageURI.getPath())
also null. Is this impossible or can somebody help?
supposing your onActivityResult checks in with the Intent object being ReturnedIntent you can do
File f = new File(ReturnedIntent.getData());
or get an inputstream and use it
getContentResolver().openInputStream(ReturnedIntent.getData())
//returns inputstream
what is the essence of this String object String filePath ?

Loading contact picture via LOOKUP_KEY and openContactPhotoInputStream convenience method

I'm modifying my app to store information on contacts using LOOKUP_KEY instead of _ID as suggested by the API docs. The only problem I'm having is that I'm no longer able to load the contact's photo.
The problematic code is this one:
InputStream s = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), contactUri);
This is returning the following error: java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts/lookup/1424i118.2312i1220228108/photo
The contactUri that I am using as argument is acquired by the following: Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, contact_key);
and in this example, contact_key is 1424i118.2312i1220228108
Based on the API docs, this helper method should work with both CONTENT_URI or CONTENT_LOOKUP_URI, which I am using.
Any ideas? Thanks.
For anyone with a similar problem, this did the trick for me:
public Bitmap getPhoto(Uri uri){
Bitmap photoBitmap = null;
String[] projection = new String[] { ContactsContract.Contacts.PHOTO_ID };
Cursor cc = getContentResolver().query(uri, projection, null, null, null);
if(cc.moveToFirst()) {
final String photoId = cc.getString(cc.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
if(photoId != null) {
final Cursor photo = managedQuery(
Data.CONTENT_URI,
new String[] {Photo.PHOTO},
Data._ID + "=?",
new String[] {photoId},
null
);
// Convert photo blob to a bitmap
if(photo.moveToFirst()) {
byte[] photoBlob = photo.getBlob(photo.getColumnIndex(Photo.PHOTO));
photoBitmap = BitmapFactory.decodeByteArray(photoBlob, 0, photoBlob.length);
}
photo.close();
}
}
cc.close();
return photoBitmap;
}

Can't get a video thumbnail in Android 2.0+

I tried to create a video thumbnail as described here.
I also read the reference here.
In my app I first let the user choose a video with:
startActivityForResult(new Intent(Intent.ACTION_GET_CONTENT).setType("video/*"), ACTIVITY_PICKVIDEO);
Then I determine the video ID with:
fileID = Integer.parseInt(contentUri.getLastPathSegment());
So, the video content://media/external/video/media/5 would have the ID 5.
Then I try to get the thumbnail bitmap with:
ContentResolver crThumb = getContentResolver();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(crThumb, fileID, MediaStore.Video.Thumbnails.MICRO_KIND, options);
There's no exception thrown but the bitmap has a width and height of -1.
I'm not sure if the ID needed in getThubnail() is actually the ID that I determined above.
Does anyone know of a working example how to get the thumbnail bitmap if you have the content Uri?
Interestingly (maybe so) I get null when trying with MediaStore.Video.Thumbnails.MINI_KIND as thumbnail size and an IllegalArgumentException ("Unsupported kind: 2") when I try FULL_SCREEN_KIND.
I'm using a Motorola Milestone with Android 2.1.
EDIT:
I also tried getting the ID with querying for the BaseColumns._ID but it turns out to be the same as in the Uri (in the given example the _ID is 5).
for getting video id try this
String[] proj = {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATA
};
Cursor cursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
proj, MediaStore.Video.Media.DISPLAY_NAME+"=?",new String[] {"name.mp4"}, null);
cursor.moveToFirst()
fileid = cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media._ID));
for getting thumbnail :
ContentResolver crThumb = getContentResolver();
Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(crThumb,fileid, MediaStore.Video.Thumbnails.MICRO_KIND, options);
iv2.setImageBitmap(curThumb);
here iv2 is imageview and name.mp4 will represent your file name

Categories

Resources