How to obtain thumbnails of video files in Android

Source: Internet
Author: User

There are three methods to obtain the thumbnail of a video file in android:

1. query from the media Repository

2. Use the ThumbnailUtils class after android 2.2

3. Call the jni file to implement the MediaMetadataRetriever class.

Advantages and disadvantages of the three methods

First, after a new video is added, SDCard needs to be re-scanned to add thumbnails to the newly added files. This method is flexible and not stable, and is suitable for simple applications.

The second method is easy to implement, but is not supported in versions earlier than 2.2.

The third method is complex but flexible. It is recommended to use

The following is a Demo of the three methods:

1. Method 1:

Public static Bitmap getVideoThumbnail (ContentResolver cr, String fileName ){
Bitmap bitmap = null;
BitmapFactory. Options options = new BitmapFactory. Options ();
Options. inDither = false;
Options. inPreferredConfig = Bitmap. Config. ARGB_8888;
// Select condition.
String whereClause = MediaStore. Video. Media. DATA + "= '"
+ FileName + "'";
Log. v (TAG, "where =" + whereClause );
// Colection of results.
Cursor cursor = cr. query (MediaStore. Video. Media. EXTERNAL_CONTENT_URI,
New String [] {MediaStore. Video. Media. _ ID}, whereClause,
Null, null );
Log. v (TAG, "cursor =" + cursor );
If (cursor = null | cursor. getCount () = 0 ){
Return null;
}
Cursor. moveToFirst ();
// Image id in image table.
String videoId = cursor. getString (cursor
. GetColumnIndex (MediaStore. Video. Media. _ ID ));
Log. v (TAG, "videoId =" + videoId );
If (videoId = null ){
Return null;
}
Cursor. close ();
Long videoIdLong = Long. parseLong (videoId );
// Via imageid get the bimap type thumbnail in thumbnail table.
Bitmap = MediaStore. Video. Thumbnails. getThumbnail (cr, videoIdLong,
Images. Thumbnails. MICRO_KIND, options );
Log. v (TAG, "bitmap =" + bitmap );
Return bitmap;
}
2. Method 2:

Three static methods through ThumbnailUtils.

1. static Bitmap createVideoThumbnail (String filePath, int kind) // obtain the thumbnail of the video file. The first parameter is the location of the video file, such as/sdcard/android123.3gp, the second parameter can be MINI_KIND or MICRO_KIND, which is ultimately related to resolution.
2. static Bitmap extractThumbnail (Bitmap source, int width, int height, int options) // scale Bitmap directly. The last parameter is defined as OPTIONS_RECYCLE_INPUT to recycle resources.
3. static Bitmap extractThumbnail (Bitmap source, int width, int height) // This is the same as the preceding method, and there is no options Option

3. Method 3:

MediaMetadataRetriever is a hidden class in android. Developers cannot call it and can only implement the same class to complete related functions.

One way is to modify the android source code and set frameworks MediaMetadataRetriever. remove the @ hide tag in java, in current. add MediaMetadataRetriever to the xml file to be available. re-compile frameworks, and the application can call the MediaMetadataRetriever class... This is not suitable for application development.

The recommended method is to implement the MediaMetadataRetriever class.

Step 1: first download the JNI Library: libmedia_jni.so

Go to the SDK Tools directory and run DDMS,
In the menu bar of DDMS, run Device-file1_e,
In the pop-up file list, select: System-Lib-libmedia_jni.so
After this file is selected, execute PULL file from device on the top of the pop-up file list to extract the libmedia_jni.so file.
Create the libs-armeabi-folder in Eclipse and put the libmedia_jni.so file in it.

Second: Implement MediaMetadataRetriever

Public class MediaMetadataRetriever
{
Static {
System. loadLibrary ("media_jni ");
Native_init ();
}
// The field below is accessed by native methods
@ SuppressWarnings ("unused ")
Private int mNativeContext;
Public MediaMetadataRetriever (){
Native_setup ();
}
/**
* Call this method before setDataSource () so that the mode becomes
* Valid tive for subsequent operations. This method can be called only once
* At the beginning if the intended mode of operation for
* MediaMetadataRetriever object remains the same for its whole lifetime,
* And thus it is unnecessary to call this method each time setDataSource ()
* Is called. If this is not never called (which is allowed), by default
* Intended mode of operation is to both capture frame and retrieve meta
* Data (I. e., MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY ).
* Often, this may not be what one wants, since doing this has negative
* Performance impact on execution time of a call to setDataSource (), since
* Both types of operations may be time consuming.
*
* @ Param mode The intended mode of operation. Can be any combination
* MODE_GET_METADATA_ONLY and MODE_CAPTURE_FRAME_ONLY:
* 1. MODE_GET_METADATA_ONLY & MODE_CAPTURE_FRAME_ONLY:
* For neither frame capture nor meta data retrieval
* 2. MODE_GET_METADATA_ONLY: For meta data retrieval only
* 3. MODE_CAPTURE_FRAME_ONLY: For frame capture only
* 4. MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY:
* For both frame capture and meta data retrieval
*/
Public native void setMode (int mode );
/**
* @ Return the current mode of operation. A negative return value indicates
* Some runtime error has occurred.
*/
Public native int getMode ();
/**
* Sets the data source (file pathname) to use. Call this
* Method before the rest of the methods in this class. This method may be
* Time-consuming.
*
* @ Param path The path of the input media file.
* @ Throws IllegalArgumentException If the path is invalid.
*/
Public native void setDataSource (String path) throws IllegalArgumentException;
/**
* Sets the data source (FileDescriptor) to use. It is the caller's
* Responsibility to close the file descriptor. It is safe to do so as soon
* As this call returns. Call this method before the rest of the methods in
* This class. This method may be time-consuming.
*
* @ Param fd the FileDescriptor for the file you want to play
* @ Param offset the offset into the file where the data to be played starts,
* In bytes. It must be non-negative
* @ Param length the length in bytes of the data to be played. It must be
* Non-negative.
* @ Throws IllegalArgumentException if the arguments are invalid
*/
Public native void setDataSource (FileDescriptor fd, long offset, long length)
Throws IllegalArgumentException;
/**
* Sets the data source (FileDescriptor) to use. It is the caller's
* Responsibility to close the file descriptor. It is safe to do so as soon
* As this call returns. Call this method before the rest of the methods in
* This class. This method may be time-consuming.
*
* @ Param fd the FileDescriptor for the file you want to play
* @ Throws IllegalArgumentException if the FileDescriptor is invalid
*/
Public void setDataSource (FileDescriptor fd)
Throws IllegalArgumentException {
// Intentionally less than LONG_MAX
SetDataSource (fd, 0, 0x7ffffffffffffl );
}
/**
* Sets the data source as a content Uri. Call this method before
* The rest of the methods in this class. This method may be time-consuming.
*
* @ Param context the Context to use when resolving the Uri
* @ Param uri the Content URI of the data you want to play
* @ Throws IllegalArgumentException if the Uri is invalid
* @ Throws SecurityException if the Uri cannot be used due to lack
* Permission.
*/
Public void setDataSource (Context context, Uri uri)
Throws IllegalArgumentException, SecurityException {
If (uri = null ){
Throw new IllegalArgumentException ();
}
String scheme = uri. getScheme ();
If (scheme = null | scheme. equals ("file ")){
SetDataSource (uri. getPath ());
Return;
}
AssetFileDescriptor fd = null;
Try {
ContentResolver resolver = context. getContentResolver ();
Try {
Fd = resolver. openAssetFileDescriptor (uri, "r ");
} Catch (FileNotFoundException e ){
Throw new IllegalArgumentException ();
}
If (fd = null ){
Throw new IllegalArgumentException ();
}
FileDescriptor descriptor = fd. getFileDescriptor ();
If (! Descriptor. valid ()){
Throw new IllegalArgumentException ();
}
// Note: using getDeclaredLength so that our behavior is the same
// As previous versions when the content provider is returning
// A full file.
If (fd. getDeclaredLength () <0 ){
SetDataSource (descriptor );
} Else {
SetDataSource (descriptor, fd. getStartOffset (), fd. getDeclaredLength ());
}
Return;
} Catch (SecurityException ex ){
} Finally {
Try {
If (fd! = Null ){
Fd. close ();
}
} Catch (IOException ioEx ){
}
}
SetDataSource (uri. toString ());
}
/**
* Call this method after setDataSource (). This method retrieves
* Meta data value associated with the keyCode.
*
* The keyCode currently supported is listed below as METADATA_XXX
* Constants. With any other value, it returns a null pointer.
*
* @ Param keyCode One of the constants listed below at the end of the class.
* @ Return The meta data value associate with the given keyCode on success;
* Null on failure.
*/
Public native String extractMetadata (int keyCode );
/**
* Call this method after setDataSource (). This method finds
* Representative frame if successful and returns it as a bitmap. This is
* Useful for generating a thumbnail for an input media source.
*
* @ Return A Bitmap containing a representative video frame, which
* Can be null, if such a frame cannot be retrieved.
*/
Public native Bitmap captureFrame ();
/**
* Call this method after setDataSource (). This method finds the optional
* Graphic or album art associated (embedded or external url linked)
* Related data source.
*
* @ Return null if no such graphic is found.
*/
Public native byte [] extractAlbumArt ();
/**
* Call it when one is done with the object. This method releases the memory
* Allocated internally.
*/
Public native void release ();
Private native void native_setup ();
Private static native void native_init ();
Private native final void native_finalize ();
@ Override
Protected void finalize () throws Throwable {
Try {
Native_finalize ();
} Finally {
Super. finalize ();
}
}
Public static final int MODE_GET_METADATA_ONLY = 0 × 01;
Public static final int MODE_CAPTURE_FRAME_ONLY = 0 × 02;
/*
* Do not change these values without updating their counterparts
* In include/media/mediametadataretriever. h!
*/
Public static final int METADATA_KEY_CD_TRACK_NUMBER = 0;
Public static final int METADATA_KEY_ALBUM = 1;
Public static final int METADATA_KEY_ARTIST = 2;
Public static final int METADATA_KEY_AUTHOR = 3;
Public static final int METADATA_KEY_COMPOSER = 4;
Public static final int METADATA_KEY_DATE = 5;
Public static final int METADATA_KEY_GENRE = 6;
Public static final int METADATA_KEY_TITLE = 7;
Public static final int METADATA_KEY_YEAR = 8;
Public static final int METADATA_KEY_DURATION = 9;
Public static final int METADATA_KEY_NUM_TRACKS = 10;
Public static final int METADATA_KEY_IS_DRM_CRIPPLED = 11;
Public static final int METADATA_KEY_CODEC = 12;
Public static final int METADATA_KEY_RATING = 13;
Public static final int METADATA_KEY_COMMENT = 14;
Public static final int METADATA_KEY_COPYRIGHT = 15;
Public static final int METADATA_KEY_BIT_RATE = 16;
Public static final int METADATA_KEY_FRAME_RATE = 17;
Public static final int METADATA_KEY_VIDEO_FORMAT = 18;
Public static final int METADATA_KEY_VIDEO_HEIGHT = 19;
Public static final int METADATA_KEY_VIDEO_WIDTH = 20;
Public static final int METADATA_KEY_WRITER = 21;
Public static final int METADATA_KEY_MIMETYPE = 22;
Public static final int METADATA_KEY_DISCNUMBER = 23;
Public static final int METADATA_KEY_ALBUMARTIST = 24;
// Add more here...
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.