Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中如何獲取視頻文件的縮略圖

Android中如何獲取視頻文件的縮略圖

編輯:關於Android編程

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

1.從媒體庫中查詢

2. android 2.2以後使用ThumbnailUtils類獲取

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

三種方法各有利弊

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

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

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

下面給出三種方法的Demo

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

通過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…
}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved