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