在 DDMS-file browser-system-lib导出jni库函数:libmedia_jni.so

然后在android项目中libs文件夹下面建立armeabi文件夹并把库函数拷贝进来;

然后创建一个android.media包(必须要在这个包下创建,否则出错),并创建MediaMetadataRetriever类,我在网上找到的这个类,Android 视频缩略图之MediaMetadataRetriever

有些方法已经不存在了,应该是版本问题,

没办法我只好看源码的jni(frameworks\base\media\jni)文件,看了之后知道有哪些函数,但是因为没接触过jni,所以要传哪些参数都没看懂,所以偷懒了

去android developers看了API(猛击这里),这样也确认了API的正确,也知道如何传参。

这样我重新在从网上获取到的这个类(MediaMetadataRetriever),再加上几行简单的 native 函数声明就简单粗暴的解决了我的问题。。

之所以导入jni库来获取缩略图是为了不用考虑版本问题,或者说简化维护版本问题。。

在android.media包下的代码:

package android.media;//package android.media;import java.io.FileDescriptor;import java.io.FileNotFoundException;import java.io.IOException;import android.content.ContentResolver;import android.content.Context;import android.content.res.AssetFileDescriptor;import android.graphics.Bitmap;import android.net.Uri;/*** MediaMetadataRetriever class provides a unified interface for retrieving* frame and meta data from an input media file.* {@hide}*/public class MediaMetadataRetriever{    static {        System.loadLibrary("media_jni");    }    // 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 at any time position if possible,      * and returns it as a bitmap. T     * his is useful for generating a thumbnail for an input data source.      * Call this method if one does not care about where the frame is located;     * @return A Bitmap containing a representative video frame,      * which can be null, if such a frame cannot be retrieved.     */    public native Bitmap getFrameAtTime();    /**     * 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 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  = 0x01;    public static final int MODE_CAPTURE_FRAME_ONLY = 0x02;    /*     * 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;    // Add more here...}




在另一个java包(com.example.thumbnaildemo)中的代码:

package com.example.thumbnaildemo;import java.io.File;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import android.media.MediaMetadataRetriever;import android.media.ThumbnailUtils;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.provider.MediaStore.Video;import android.text.format.DateFormat;import android.util.Log;import android.widget.ImageView;public class MainActivity extends Activity {    final static String TAG = "MainActivity";ImageView thumbnails;@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.i(TAG,"------------------onCreate---------------------------");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);thumbnails=(ImageView)findViewById(R.id.imageView2);/*InputStream input = getResources().openRawResource(R.drawable.girl);        BitmapDrawable girl = new BitmapDrawable(input);        Bitmap bitmap = girl.getBitmap();        bitmap =ThumbnailUtils.extractThumbnail(bitmap, 50, 50);        thumbnails.setImageBitmap(bitmap);*/        File file = new File("/sdcard/mp4/china.mp4");        Bitmap bitmap = createVideoThumbnail(file.getAbsolutePath());        thumbnails.setImageBitmap(bitmap);/*List



更多相关文章

  1. Android(安卓)简史
  2. 从assets文件夹中读取txt文件
  3. Android(安卓)N及以上版本应用安装包下载完成自动弹出安装界面的
  4. Android(安卓)的一些基本问题解决方法(android studio)
  5. MyEclip1se8.5搭建Android环境
  6. 零基础学习教程之Linux下搭建android开发环境
  7. Java.lang.UnsatisfiedLinkError :nativeSetExternalAssetPath错
  8. MTP 看不到软件创建的文件夹(Android端)
  9. Tensorflow编译android平台的so库和jar包

随机推荐

  1. Springboot中的javaConfig详解(基于Spring
  2. Android(安卓)平滑和立体翻页效果1
  3. Android(安卓)Canvas绘图抗锯齿解决方法
  4. Android(安卓)ListView的常见用法
  5. [原]Android(安卓)插件 根据布局xml自动
  6. 基于iMAG开发的ITeye手机客户端
  7. android universalimageloader 几点改进
  8. 大数据开发工程师
  9. Android压力测试快速入门教程(图解)——Mon
  10. Android基础——通过activity和XML绑定实