android 中獲取視頻文件的縮略圖(非原創)

在android中獲取視頻文件的縮略圖有三種方法: java

1.從媒體庫中查詢 android

2. android 2.2之後使用ThumbnailUtils類獲取 less

3.調用jni文件,實現MediaMetadataRetriever類 ide

三種方法各有利弊 this

第一種方法,新視頻增長後須要SDCard從新掃描才能給新增長的文件添加縮略圖,靈活性差,並且不是很穩定,適合簡單應用 url

第二種方法,實現簡單,但2.2之前的版本不支持 rest

第三種方法,實現複雜,但比較靈活,推薦使用orm

下面給出三種方法的Demo視頻

1.第一種方法:xml

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. 第二種方法:

經過ThumbnailUtils的三種靜態方法。

1. static Bitmap createVideoThumbnail(String filePath, int kind) //獲取視頻文件的縮略圖,第一個參數爲視頻文件的位置,好比/sdcard/android123.3gp,而第二個參數能夠爲MINI_KIND或 MICRO_KIND最終和分辨率有關
2. static Bitmap extractThumbnail(Bitmap source, int width, int height, int options) //直接對Bitmap進行縮略操做,最後一個參數定義爲OPTIONS_RECYCLE_INPUT ,來回收資源
3. static Bitmap extractThumbnail(Bitmap source, int width, int height) // 這個和上面的方法同樣,無options選項

3. 第三種方法:

MediaMetadataRetriever是android中隱藏的一個類,開發者沒法調用,只能實現一個相同的類來完成相關功能。

一種方式是修改android源碼,將frameworks  MediaMetadataRetriever.java中@hide標籤去掉,在current.xml中添加 MediaMetadataRetriever到可用.從新編譯frameworks,應用就能夠調用到MediaMetadataRetriever這個類了…這樣是不適合應用開發的。

推薦的方法是實現MediaMetadataRetriever類

第一步:首先須要下載JNI庫:libmedia_jni.so

進入SDK的Tools目錄下,運行DDMS,
在DDMS中的菜單欄中,執行Device–FileExplore,
在彈出的文件列表中選擇: System-Lib-libmedia_jni.so
選中這個文件後, 在彈出的文件列表的又上腳執行PULL file from device,提取出libmedia_jni.so文件
在Eclipse中新建文件夾libs-armeabi-,在裏面放入libmedia_jni.so文件

第二部:實現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 * effective for subsequent operations. This method can be called only once * at the beginning if the intended mode of operation for a * 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 the * 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 of * 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, 0x7ffffffffffffffL); } /** * 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 of * 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 the * 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 a * 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) the * 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… }

相關文章
相關標籤/搜索