MediaMetadataRetrieverTest.java revision f6bd1ea0c79516a5ef3c0c463761deec1a80e419
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 com.android.mediaframeworktest.unit;
18
19import android.util.Log;
20import android.media.MediaMetadataRetriever;
21import android.graphics.Bitmap;
22import java.io.FileOutputStream;
23import android.test.AndroidTestCase;
24import com.android.mediaframeworktest.MediaNames;
25import com.android.mediaframeworktest.MediaProfileReader;
26import android.test.suitebuilder.annotation.*;
27
28public class MediaMetadataRetrieverTest extends AndroidTestCase {
29
30    private static final String TAG         = "MediaMetadataRetrieverTest";
31
32    // Test album art extraction.
33    @MediumTest
34    public static void testAlbumArt() throws Exception {
35        Log.v(TAG, "testAlbumArt starts.");
36        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
37        boolean supportWMA = MediaProfileReader.getWMAEnable();
38        boolean hasFailed = false;
39        boolean supportWMV = MediaProfileReader.getWMVEnable();
40        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
41        for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
42            try {
43                Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
44                if ((MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
45                    (MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
46                   ) {
47                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
48                    continue;
49                }
50                retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
51                byte[] albumArt = retriever.extractAlbumArt();
52
53                // TODO:
54                // A better test would be to compare the retrieved album art with the
55                // known result.
56                if (albumArt == null) {  // Do we have expect in JUnit?
57                    Log.e(TAG, "Fails to extract album art for " + MediaNames.ALBUMART_TEST_FILES[i]);
58                    hasFailed = true;
59                }
60            } catch(Exception e) {
61                Log.e(TAG, "Fails to setDataSource for " + MediaNames.ALBUMART_TEST_FILES[i]);
62                hasFailed = true;
63            }
64            Thread.yield();  // Don't be evil
65        }
66        retriever.release();
67        Log.v(TAG, "testAlbumArt completes.");
68        assertTrue(!hasFailed);
69    }
70
71    // Test frame capture
72    @LargeTest
73    public static void testThumbnailCapture() throws Exception {
74        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
75        boolean supportWMA = MediaProfileReader.getWMAEnable();
76        boolean supportWMV = MediaProfileReader.getWMVEnable();
77        boolean hasFailed = false;
78        Log.v(TAG, "Thumbnail processing starts");
79        long startedAt = System.currentTimeMillis();
80        for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
81            try {
82                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
83                if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
84                    (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
85                   ) {
86                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
87                    continue;
88                }
89                retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
90                Bitmap bitmap = retriever.getFrameAtTime(-1);
91                assertTrue(bitmap != null);
92                try {
93                    java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg");
94                    bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
95                    stream.close();
96                } catch (Exception e) {
97                    Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
98                    hasFailed = true;
99                    Log.e(TAG, e.toString());
100                }
101            } catch(Exception e) {
102                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
103                hasFailed = true;
104            }
105            Thread.yield();  // Don't be evil
106        }
107        long endedAt = System.currentTimeMillis();
108        retriever.release();
109        assertTrue(!hasFailed);
110        Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms");
111    }
112
113    @LargeTest
114    public static void testMetadataRetrieval() throws Exception {
115        boolean supportWMA = MediaProfileReader.getWMAEnable();
116        boolean supportWMV = MediaProfileReader.getWMVEnable();
117        boolean hasFailed = false;
118        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
119        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
120        for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
121            try {
122                Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
123                if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
124                    (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
125                   ) {
126                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
127                    continue;
128                }
129                retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
130                extractAllSupportedMetadataValues(retriever);
131            } catch(Exception e) {
132                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
133                hasFailed = true;
134            }
135            Thread.yield();  // Don't be evil
136        }
137        retriever.release();
138        assertTrue(!hasFailed);
139    }
140
141    // If the specified call order and valid media file is used, no exception
142    // should be thrown.
143    @MediumTest
144    public static void testBasicNormalMethodCallSequence() throws Exception {
145        boolean hasFailed = false;
146        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
147        try {
148            retriever.setDataSource(MediaNames.TEST_PATH_1);
149            Bitmap bitmap = retriever.getFrameAtTime(-1);
150            assertTrue(bitmap != null);
151            try {
152                java.io.OutputStream stream = new FileOutputStream("/sdcard/thumbnailout.jpg");
153                bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
154                stream.close();
155            } catch (Exception e) {
156                throw new Exception("Fails to convert the bitmap to a JPEG file for " + MediaNames.TEST_PATH_1, e);
157            }
158            extractAllSupportedMetadataValues(retriever);
159        } catch(Exception e) {
160            Log.e(TAG, "Fails to setDataSource for " + MediaNames.TEST_PATH_1, e);
161            hasFailed = true;
162        }
163        retriever.release();
164        assertTrue(!hasFailed);
165    }
166
167    // If setDataSource() has not been called, both getFrameAtTime() and extractMetadata() must
168    // return null.
169    @MediumTest
170    public static void testBasicAbnormalMethodCallSequence() {
171        boolean hasFailed = false;
172        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
173        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
174        if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) != null) {
175            Log.e(TAG, "No album metadata expected, but is available");
176            hasFailed = true;
177        }
178        if (retriever.getFrameAtTime(-1) != null) {
179            Log.e(TAG, "No frame expected, but is available");
180            hasFailed = true;
181        }
182        assertTrue(!hasFailed);
183    }
184
185    // Test setDataSource()
186    @MediumTest
187    public static void testSetDataSource() {
188        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
189        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
190        boolean hasFailed = false;
191
192        // Null pointer argument
193        try {
194            String path = null;
195            retriever.setDataSource(path);
196            Log.e(TAG, "IllegalArgumentException failed to be thrown.");
197            hasFailed = true;
198        } catch(Exception e) {
199            if (!(e instanceof IllegalArgumentException)) {
200                Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
201                hasFailed = true;
202            }
203        }
204
205        // Use mem:// path
206        try {
207            retriever.setDataSource(MediaNames.TEST_PATH_5);
208            Log.e(TAG, "IllegalArgumentException failed to be thrown.");
209            hasFailed = true;
210        } catch(Exception e) {
211            if (!(e instanceof IllegalArgumentException)) {
212                Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
213                hasFailed = true;
214            }
215        }
216
217        // The pathname does not correspond to any existing file
218        try {
219            retriever.setDataSource(MediaNames.TEST_PATH_4);
220            Log.e(TAG, "RuntimeException failed to be thrown.");
221            hasFailed = true;
222        } catch(Exception e) {
223            if (!(e instanceof RuntimeException)) {
224                Log.e(TAG, "Expected a RuntimeException, but got a different exception");
225                hasFailed = true;
226            }
227        }
228
229        // The pathname does correspond to a file, but this file
230        // is not a valid media file
231        try {
232            retriever.setDataSource(MediaNames.TEST_PATH_3);
233            Log.e(TAG, "RuntimeException failed to be thrown.");
234            hasFailed = true;
235        } catch(Exception e) {
236            if (!(e instanceof RuntimeException)) {
237                Log.e(TAG, "Expected a RuntimeException, but got a different exception");
238                hasFailed = true;
239            }
240        }
241
242        retriever.release();
243        assertTrue(!hasFailed);
244    }
245
246    @MediumTest
247    public static void testIntendedUsage() {
248        // By default, capture frame and retrieve metadata
249        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
250        boolean hasFailed = false;
251        retriever.setDataSource(MediaNames.TEST_PATH_1);
252        assertTrue(retriever.getFrameAtTime(-1) != null);
253        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
254
255        // Do not capture frame or retrieve metadata
256        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY & MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
257        retriever.setDataSource(MediaNames.TEST_PATH_1);
258        if (retriever.getFrameAtTime(-1) != null) {
259            Log.e(TAG, "No frame expected, but is available");
260            hasFailed = true;
261        }
262        if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null) {
263            Log.e(TAG, "No num track metadata expected, but is available");
264            hasFailed = true;
265        }
266
267        // Capture frame only
268        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
269        retriever.setDataSource(MediaNames.TEST_PATH_1);
270        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null);
271
272        // Retriever metadata only
273        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
274        retriever.setDataSource(MediaNames.TEST_PATH_1);
275        if (retriever.getFrameAtTime(-1) != null) {
276            Log.e(TAG, "No frame expected, but is available");
277            hasFailed = true;
278        }
279
280        // Capture frame and retrieve metadata
281        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY | MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
282        retriever.setDataSource(MediaNames.TEST_PATH_1);
283        assertTrue(retriever.getFrameAtTime(-1) != null);
284        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
285        retriever.release();
286        assertTrue(!hasFailed);
287    }
288
289    // TODO:
290    // Encode and test for the correct mix of metadata elements on a per-file basis?
291    // We should be able to compare the actual returned metadata with the expected metadata
292    // with each given sample test file.
293    private static void extractAllSupportedMetadataValues(MediaMetadataRetriever retriever) {
294        String value = null;
295        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER)) == null? "not found": value);
296        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) == null? "not found": value);
297        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS)) == null? "not found": value);
298        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)) == null? "not found": value);
299        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)) == null? "not found": value);
300        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_AUTHOR)) == null? "not found": value);
301        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER)) == null? "not found": value);
302        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)) == null? "not found": value);
303        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)) == null? "not found": value);
304        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)) == null? "not found": value);
305        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)) == null? "not found": value);
306    }
307}
308