MediaMetadataRetriever.java revision b798689749c64baba81f02e10cf2157c747d6b46
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.media; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.graphics.Bitmap; 22import android.net.Uri; 23import android.os.ParcelFileDescriptor; 24import java.io.FileDescriptor; 25import java.io.IOException; 26import java.io.FileNotFoundException; 27 28/** 29 * MediaMetadataRetriever class provides a unified interface for retrieving 30 * frame and meta data from an input media file. 31 * {@hide} 32 */ 33public class MediaMetadataRetriever 34{ 35 static { 36 System.loadLibrary("media_jni"); 37 } 38 39 // The field below is accessed by native methods 40 @SuppressWarnings("unused") 41 private int mNativeContext; 42 43 public MediaMetadataRetriever() { 44 native_setup(); 45 } 46 47 /** 48 * Call this method before setDataSource() so that the mode becomes 49 * effective for subsequent operations. This method can be called only once 50 * at the beginning if the intended mode of operation for a 51 * MediaMetadataRetriever object remains the same for its whole lifetime, 52 * and thus it is unnecessary to call this method each time setDataSource() 53 * is called. If this is not never called (which is allowed), by default the 54 * intended mode of operation is to both capture frame and retrieve meta 55 * data (i.e., MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY). 56 * Often, this may not be what one wants, since doing this has negative 57 * performance impact on execution time of a call to setDataSource(), since 58 * both types of operations may be time consuming. 59 * 60 * @param mode The intended mode of operation. Can be any combination of 61 * MODE_GET_METADATA_ONLY and MODE_CAPTURE_FRAME_ONLY: 62 * 1. MODE_GET_METADATA_ONLY & MODE_CAPTURE_FRAME_ONLY: 63 * For neither frame capture nor meta data retrieval 64 * 2. MODE_GET_METADATA_ONLY: For meta data retrieval only 65 * 3. MODE_CAPTURE_FRAME_ONLY: For frame capture only 66 * 4. MODE_GET_METADATA_ONLY | MODE_CAPTURE_FRAME_ONLY: 67 * For both frame capture and meta data retrieval 68 */ 69 public native void setMode(int mode); 70 71 /** 72 * @return the current mode of operation. A negative return value indicates 73 * some runtime error has occurred. 74 */ 75 public native int getMode(); 76 77 /** 78 * Sets the data source (file pathname) to use. Call this 79 * method before the rest of the methods in this class. This method may be 80 * time-consuming. 81 * 82 * @param path The path of the input media file. 83 * @throws IllegalArgumentException If the path is invalid. 84 */ 85 public native void setDataSource(String path) throws IllegalArgumentException; 86 87 /** 88 * Sets the data source (FileDescriptor) to use. It is the caller's 89 * responsibility to close the file descriptor. It is safe to do so as soon 90 * as this call returns. Call this method before the rest of the methods in 91 * this class. This method may be time-consuming. 92 * 93 * @param fd the FileDescriptor for the file you want to play 94 * @param offset the offset into the file where the data to be played starts, 95 * in bytes. It must be non-negative 96 * @param length the length in bytes of the data to be played. It must be 97 * non-negative. 98 * @throws IllegalArgumentException if the arguments are invalid 99 */ 100 public native void setDataSource(FileDescriptor fd, long offset, long length) 101 throws IllegalArgumentException; 102 103 /** 104 * Sets the data source (FileDescriptor) to use. It is the caller's 105 * responsibility to close the file descriptor. It is safe to do so as soon 106 * as this call returns. Call this method before the rest of the methods in 107 * this class. This method may be time-consuming. 108 * 109 * @param fd the FileDescriptor for the file you want to play 110 * @throws IllegalArgumentException if the FileDescriptor is invalid 111 */ 112 public void setDataSource(FileDescriptor fd) 113 throws IllegalArgumentException { 114 // intentionally less than LONG_MAX 115 setDataSource(fd, 0, 0x7ffffffffffffffL); 116 } 117 118 /** 119 * Sets the data source as a content Uri. Call this method before 120 * the rest of the methods in this class. This method may be time-consuming. 121 * 122 * @param context the Context to use when resolving the Uri 123 * @param uri the Content URI of the data you want to play 124 * @throws IllegalArgumentException if the Uri is invalid 125 * @throws SecurityException if the Uri cannot be used due to lack of 126 * permission. 127 */ 128 public void setDataSource(Context context, Uri uri) 129 throws IllegalArgumentException, SecurityException { 130 if (uri == null) { 131 throw new IllegalArgumentException(); 132 } 133 134 String scheme = uri.getScheme(); 135 if(scheme == null || scheme.equals("file")) { 136 setDataSource(uri.getPath()); 137 return; 138 } 139 140 ParcelFileDescriptor fd = null; 141 try { 142 ContentResolver resolver = context.getContentResolver(); 143 try { 144 fd = resolver.openFileDescriptor(uri, "r"); 145 } catch(FileNotFoundException e) { 146 throw new IllegalArgumentException(); 147 } 148 if (fd == null) { 149 throw new IllegalArgumentException(); 150 } 151 FileDescriptor descriptor = fd.getFileDescriptor(); 152 if (!descriptor.valid()) { 153 throw new IllegalArgumentException(); 154 } 155 setDataSource(descriptor); 156 return; 157 } catch (SecurityException ex) { 158 } finally { 159 try { 160 if (fd != null) { 161 fd.close(); 162 } 163 } catch(IOException ioEx) { 164 } 165 } 166 setDataSource(uri.toString()); 167 } 168 169 /** 170 * Call this method after setDataSource(). This method retrieves the 171 * meta data value associated with the keyCode. 172 * 173 * The keyCode currently supported is listed below as METADATA_XXX 174 * constants. With any other value, it returns a null pointer. 175 * 176 * @param keyCode One of the constants listed below at the end of the class. 177 * @return The meta data value associate with the given keyCode on success; 178 * null on failure. 179 */ 180 public native String extractMetadata(int keyCode); 181 182 /** 183 * Call this method after setDataSource(). This method finds a 184 * representative frame if successful and returns it as a bitmap. This is 185 * useful for generating a thumbnail for an input media source. 186 * 187 * @return A Bitmap containing a representative video frame, which 188 * can be null, if such a frame cannot be retrieved. 189 */ 190 public native Bitmap captureFrame(); 191 192 /** 193 * Call this method after setDataSource(). This method finds the optional 194 * graphic or album art associated (embedded or external url linked) the 195 * related data source. 196 * 197 * @return null if no such graphic is found. 198 */ 199 public native byte[] extractAlbumArt(); 200 201 /** 202 * Call it when one is done with the object. This method releases the memory 203 * allocated internally. 204 */ 205 public native void release(); 206 private native void native_setup(); 207 208 private native final void native_finalize(); 209 210 @Override 211 protected void finalize() throws Throwable { 212 try { 213 native_finalize(); 214 } finally { 215 super.finalize(); 216 } 217 } 218 219 public static final int MODE_GET_METADATA_ONLY = 0x01; 220 public static final int MODE_CAPTURE_FRAME_ONLY = 0x02; 221 222 /* 223 * Do not change these values without updating their counterparts 224 * in include/media/mediametadataretriever.h! 225 */ 226 public static final int METADATA_KEY_CD_TRACK_NUMBER = 0; 227 public static final int METADATA_KEY_ALBUM = 1; 228 public static final int METADATA_KEY_ARTIST = 2; 229 public static final int METADATA_KEY_AUTHOR = 3; 230 public static final int METADATA_KEY_COMPOSER = 4; 231 public static final int METADATA_KEY_DATE = 5; 232 public static final int METADATA_KEY_GENRE = 6; 233 public static final int METADATA_KEY_TITLE = 7; 234 public static final int METADATA_KEY_YEAR = 8; 235 public static final int METADATA_KEY_DURATION = 9; 236 public static final int METADATA_KEY_NUM_TRACKS = 10; 237 public static final int METADATA_KEY_IS_DRM_CRIPPLED = 11; 238 public static final int METADATA_KEY_CODEC = 12; 239 public static final int METADATA_KEY_RATING = 13; 240 public static final int METADATA_KEY_COMMENT = 14; 241 public static final int METADATA_KEY_COPYRIGHT = 15; 242 public static final int METADATA_KEY_BIT_RATE = 16; 243 public static final int METADATA_KEY_FRAME_RATE = 17; 244 public static final int METADATA_KEY_VIDEO_FORMAT = 18; 245 public static final int METADATA_KEY_VIDEO_HEIGHT = 19; 246 public static final int METADATA_KEY_VIDEO_WIDTH = 20; 247 // Add more here... 248} 249