MediaRecorder.java revision b0bd62f96cd81f5209ea01e4f484f5b35a389cc0
1/*
2 * Copyright (C) 2007 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.annotation.NonNull;
20import android.annotation.SystemApi;
21import android.app.ActivityThread;
22import android.hardware.Camera;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import android.util.Log;
28import android.view.Surface;
29
30import java.io.FileDescriptor;
31import java.io.IOException;
32import java.io.RandomAccessFile;
33import java.lang.ref.WeakReference;
34
35/**
36 * Used to record audio and video. The recording control is based on a
37 * simple state machine (see below).
38 *
39 * <p><img src="{@docRoot}images/mediarecorder_state_diagram.gif" border="0" />
40 * </p>
41 *
42 * <p>A common case of using MediaRecorder to record audio works as follows:
43 *
44 * <pre>MediaRecorder recorder = new MediaRecorder();
45 * recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
46 * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
47 * recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
48 * recorder.setOutputFile(PATH_NAME);
49 * recorder.prepare();
50 * recorder.start();   // Recording is now started
51 * ...
52 * recorder.stop();
53 * recorder.reset();   // You can reuse the object by going back to setAudioSource() step
54 * recorder.release(); // Now the object cannot be reused
55 * </pre>
56 *
57 * <p>Applications may want to register for informational and error
58 * events in order to be informed of some internal update and possible
59 * runtime errors during recording. Registration for such events is
60 * done by setting the appropriate listeners (via calls
61 * (to {@link #setOnInfoListener(OnInfoListener)}setOnInfoListener and/or
62 * {@link #setOnErrorListener(OnErrorListener)}setOnErrorListener).
63 * In order to receive the respective callback associated with these listeners,
64 * applications are required to create MediaRecorder objects on threads with a
65 * Looper running (the main UI thread by default already has a Looper running).
66 *
67 * <p><strong>Note:</strong> Currently, MediaRecorder does not work on the emulator.
68 *
69 * <div class="special reference">
70 * <h3>Developer Guides</h3>
71 * <p>For more information about how to use MediaRecorder for recording video, read the
72 * <a href="{@docRoot}guide/topics/media/camera.html#capture-video">Camera</a> developer guide.
73 * For more information about how to use MediaRecorder for recording sound, read the
74 * <a href="{@docRoot}guide/topics/media/audio-capture.html">Audio Capture</a> developer guide.</p>
75 * </div>
76 */
77public class MediaRecorder
78{
79    static {
80        System.loadLibrary("media_jni");
81        native_init();
82    }
83    private final static String TAG = "MediaRecorder";
84
85    // The two fields below are accessed by native methods
86    @SuppressWarnings("unused")
87    private long mNativeContext;
88
89    @SuppressWarnings("unused")
90    private Surface mSurface;
91
92    private String mPath;
93    private FileDescriptor mFd;
94    private EventHandler mEventHandler;
95    private OnErrorListener mOnErrorListener;
96    private OnInfoListener mOnInfoListener;
97
98    /**
99     * Default constructor.
100     */
101    public MediaRecorder() {
102
103        Looper looper;
104        if ((looper = Looper.myLooper()) != null) {
105            mEventHandler = new EventHandler(this, looper);
106        } else if ((looper = Looper.getMainLooper()) != null) {
107            mEventHandler = new EventHandler(this, looper);
108        } else {
109            mEventHandler = null;
110        }
111
112        String packageName = ActivityThread.currentPackageName();
113        /* Native setup requires a weak reference to our object.
114         * It's easier to create it here than in C++.
115         */
116        native_setup(new WeakReference<MediaRecorder>(this), packageName,
117                ActivityThread.currentOpPackageName());
118    }
119
120    /**
121     * Sets a {@link android.hardware.Camera} to use for recording.
122     *
123     * <p>Use this function to switch quickly between preview and capture mode without a teardown of
124     * the camera object. {@link android.hardware.Camera#unlock()} should be called before
125     * this. Must call before {@link #prepare}.</p>
126     *
127     * @param c the Camera to use for recording
128     * @deprecated Use {@link #getSurface} and the {@link android.hardware.camera2} API instead.
129     */
130    @Deprecated
131    public native void setCamera(Camera c);
132
133    /**
134     * Gets the surface to record from when using SURFACE video source.
135     *
136     * <p> May only be called after {@link #prepare}. Frames rendered to the Surface before
137     * {@link #start} will be discarded.</p>
138     *
139     * @throws IllegalStateException if it is called before {@link #prepare}, after
140     * {@link #stop}, or is called when VideoSource is not set to SURFACE.
141     * @see android.media.MediaRecorder.VideoSource
142     */
143    public native Surface getSurface();
144
145    /**
146     * Configures the recorder to use a persistent surface when using SURFACE video source.
147     * <p> May only be called before {@link #prepare}. If called, {@link #getSurface} should
148     * not be used and will throw IllegalStateException. Frames rendered to the Surface
149     * before {@link #start} will be discarded.</p>
150
151     * @param surface a persistent input surface created by
152     *           {@link MediaCodec#createPersistentInputSurface}
153     * @throws IllegalStateException if it is called after {@link #prepare} and before
154     * {@link #stop}.
155     * @throws IllegalArgumentException if the surface was not created by
156     *           {@link MediaCodec#createPersistentInputSurface}.
157     * @see MediaCodec#createPersistentInputSurface
158     * @see MediaRecorder.VideoSource
159     */
160    public void setInputSurface(@NonNull Surface surface) {
161        if (!(surface instanceof MediaCodec.PersistentSurface)) {
162            throw new IllegalArgumentException("not a PersistentSurface");
163        }
164        native_setInputSurface(surface);
165    }
166
167    private native final void native_setInputSurface(@NonNull Surface surface);
168
169    /**
170     * Sets a Surface to show a preview of recorded media (video). Calls this
171     * before prepare() to make sure that the desirable preview display is
172     * set. If {@link #setCamera(Camera)} is used and the surface has been
173     * already set to the camera, application do not need to call this. If
174     * this is called with non-null surface, the preview surface of the camera
175     * will be replaced by the new surface. If this method is called with null
176     * surface or not called at all, media recorder will not change the preview
177     * surface of the camera.
178     *
179     * @param sv the Surface to use for the preview
180     * @see android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)
181     */
182    public void setPreviewDisplay(Surface sv) {
183        mSurface = sv;
184    }
185
186    /**
187     * Defines the audio source.
188     * An audio source defines both a default physical source of audio signal, and a recording
189     * configuration. These constants are for instance used
190     * in {@link MediaRecorder#setAudioSource(int)} or
191     * {@link AudioRecord.Builder#setAudioSource(int)}.
192     */
193    public final class AudioSource {
194
195        private AudioSource() {}
196
197        /** @hide */
198        public final static int AUDIO_SOURCE_INVALID = -1;
199
200      /* Do not change these values without updating their counterparts
201       * in system/media/audio/include/system/audio.h!
202       */
203
204        /** Default audio source **/
205        public static final int DEFAULT = 0;
206
207        /** Microphone audio source */
208        public static final int MIC = 1;
209
210        /** Voice call uplink (Tx) audio source.
211         * <p>
212         * Capturing from <code>VOICE_UPLINK</code> source requires the
213         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
214         * This permission is reserved for use by system components and is not available to
215         * third-party applications.
216         * </p>
217         */
218        public static final int VOICE_UPLINK = 2;
219
220        /** Voice call downlink (Rx) audio source.
221         * <p>
222         * Capturing from <code>VOICE_DOWNLINK</code> source requires the
223         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
224         * This permission is reserved for use by system components and is not available to
225         * third-party applications.
226         * </p>
227         */
228        public static final int VOICE_DOWNLINK = 3;
229
230        /** Voice call uplink + downlink audio source
231         * <p>
232         * Capturing from <code>VOICE_CALL</code> source requires the
233         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
234         * This permission is reserved for use by system components and is not available to
235         * third-party applications.
236         * </p>
237         */
238        public static final int VOICE_CALL = 4;
239
240        /** Microphone audio source tuned for video recording, with the same orientation
241         *  as the camera if available. */
242        public static final int CAMCORDER = 5;
243
244        /** Microphone audio source tuned for voice recognition. */
245        public static final int VOICE_RECOGNITION = 6;
246
247        /** Microphone audio source tuned for voice communications such as VoIP. It
248         *  will for instance take advantage of echo cancellation or automatic gain control
249         *  if available.
250         */
251        public static final int VOICE_COMMUNICATION = 7;
252
253        /**
254         * Audio source for a submix of audio streams to be presented remotely.
255         * <p>
256         * An application can use this audio source to capture a mix of audio streams
257         * that should be transmitted to a remote receiver such as a Wifi display.
258         * While recording is active, these audio streams are redirected to the remote
259         * submix instead of being played on the device speaker or headset.
260         * </p><p>
261         * Certain streams are excluded from the remote submix, including
262         * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_ALARM},
263         * and {@link AudioManager#STREAM_NOTIFICATION}.  These streams will continue
264         * to be presented locally as usual.
265         * </p><p>
266         * Capturing the remote submix audio requires the
267         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
268         * This permission is reserved for use by system components and is not available to
269         * third-party applications.
270         * </p>
271         */
272        public static final int REMOTE_SUBMIX = 8;
273
274        /** Microphone audio source tuned for unprocessed (raw) sound if available, behaves like
275         *  {@link #DEFAULT} otherwise. */
276        public static final int UNPROCESSED = 9;
277
278        /**
279         * Audio source for capturing broadcast radio tuner output.
280         * @hide
281         */
282        @SystemApi
283        public static final int RADIO_TUNER = 1998;
284
285        /**
286         * Audio source for preemptible, low-priority software hotword detection
287         * It presents the same gain and pre processing tuning as {@link #VOICE_RECOGNITION}.
288         * <p>
289         * An application should use this audio source when it wishes to do
290         * always-on software hotword detection, while gracefully giving in to any other application
291         * that might want to read from the microphone.
292         * </p>
293         * This is a hidden audio source.
294         * @hide
295         */
296        @SystemApi
297        public static final int HOTWORD = 1999;
298    }
299
300    // TODO make AudioSource static (API change) and move this method inside the AudioSource class
301    /**
302     * @hide
303     * @param source An audio source to test
304     * @return true if the source is only visible to system components
305     */
306    public static boolean isSystemOnlyAudioSource(int source) {
307        switch(source) {
308        case AudioSource.DEFAULT:
309        case AudioSource.MIC:
310        case AudioSource.VOICE_UPLINK:
311        case AudioSource.VOICE_DOWNLINK:
312        case AudioSource.VOICE_CALL:
313        case AudioSource.CAMCORDER:
314        case AudioSource.VOICE_RECOGNITION:
315        case AudioSource.VOICE_COMMUNICATION:
316        //case REMOTE_SUBMIX:  considered "system" as it requires system permissions
317        case AudioSource.UNPROCESSED:
318            return false;
319        default:
320            return true;
321        }
322    }
323
324    /**
325     * Defines the video source. These constants are used with
326     * {@link MediaRecorder#setVideoSource(int)}.
327     */
328    public final class VideoSource {
329      /* Do not change these values without updating their counterparts
330       * in include/media/mediarecorder.h!
331       */
332        private VideoSource() {}
333        public static final int DEFAULT = 0;
334        /** Camera video source
335         * <p>
336         * Using the {@link android.hardware.Camera} API as video source.
337         * </p>
338         */
339        public static final int CAMERA = 1;
340        /** Surface video source
341         * <p>
342         * Using a Surface as video source.
343         * </p><p>
344         * This flag must be used when recording from an
345         * {@link android.hardware.camera2} API source.
346         * </p><p>
347         * When using this video source type, use {@link MediaRecorder#getSurface()}
348         * to retrieve the surface created by MediaRecorder.
349         */
350        public static final int SURFACE = 2;
351    }
352
353    /**
354     * Defines the output format. These constants are used with
355     * {@link MediaRecorder#setOutputFormat(int)}.
356     */
357    public final class OutputFormat {
358      /* Do not change these values without updating their counterparts
359       * in include/media/mediarecorder.h!
360       */
361        private OutputFormat() {}
362        public static final int DEFAULT = 0;
363        /** 3GPP media file format*/
364        public static final int THREE_GPP = 1;
365        /** MPEG4 media file format*/
366        public static final int MPEG_4 = 2;
367
368        /** The following formats are audio only .aac or .amr formats */
369
370        /**
371         * AMR NB file format
372         * @deprecated  Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
373         */
374        public static final int RAW_AMR = 3;
375
376        /** AMR NB file format */
377        public static final int AMR_NB = 3;
378
379        /** AMR WB file format */
380        public static final int AMR_WB = 4;
381
382        /** @hide AAC ADIF file format */
383        public static final int AAC_ADIF = 5;
384
385        /** AAC ADTS file format */
386        public static final int AAC_ADTS = 6;
387
388        /** @hide Stream over a socket, limited to a single stream */
389        public static final int OUTPUT_FORMAT_RTP_AVP = 7;
390
391        /** H.264/AAC data encapsulated in MPEG2/TS */
392        public static final int MPEG_2_TS = 8;
393
394        /** VP8/VORBIS data in a WEBM container */
395        public static final int WEBM = 9;
396    };
397
398    /**
399     * Defines the audio encoding. These constants are used with
400     * {@link MediaRecorder#setAudioEncoder(int)}.
401     */
402    public final class AudioEncoder {
403      /* Do not change these values without updating their counterparts
404       * in include/media/mediarecorder.h!
405       */
406        private AudioEncoder() {}
407        public static final int DEFAULT = 0;
408        /** AMR (Narrowband) audio codec */
409        public static final int AMR_NB = 1;
410        /** AMR (Wideband) audio codec */
411        public static final int AMR_WB = 2;
412        /** AAC Low Complexity (AAC-LC) audio codec */
413        public static final int AAC = 3;
414        /** High Efficiency AAC (HE-AAC) audio codec */
415        public static final int HE_AAC = 4;
416        /** Enhanced Low Delay AAC (AAC-ELD) audio codec */
417        public static final int AAC_ELD = 5;
418        /** Ogg Vorbis audio codec */
419        public static final int VORBIS = 6;
420    }
421
422    /**
423     * Defines the video encoding. These constants are used with
424     * {@link MediaRecorder#setVideoEncoder(int)}.
425     */
426    public final class VideoEncoder {
427      /* Do not change these values without updating their counterparts
428       * in include/media/mediarecorder.h!
429       */
430        private VideoEncoder() {}
431        public static final int DEFAULT = 0;
432        public static final int H263 = 1;
433        public static final int H264 = 2;
434        public static final int MPEG_4_SP = 3;
435        public static final int VP8 = 4;
436        public static final int HEVC = 5;
437    }
438
439    /**
440     * Sets the audio source to be used for recording. If this method is not
441     * called, the output file will not contain an audio track. The source needs
442     * to be specified before setting recording-parameters or encoders. Call
443     * this only before setOutputFormat().
444     *
445     * @param audio_source the audio source to use
446     * @throws IllegalStateException if it is called after setOutputFormat()
447     * @see android.media.MediaRecorder.AudioSource
448     */
449    public native void setAudioSource(int audio_source)
450            throws IllegalStateException;
451
452    /**
453     * Gets the maximum value for audio sources.
454     * @see android.media.MediaRecorder.AudioSource
455     */
456    public static final int getAudioSourceMax() {
457        return AudioSource.UNPROCESSED;
458    }
459
460    /**
461     * Sets the video source to be used for recording. If this method is not
462     * called, the output file will not contain an video track. The source needs
463     * to be specified before setting recording-parameters or encoders. Call
464     * this only before setOutputFormat().
465     *
466     * @param video_source the video source to use
467     * @throws IllegalStateException if it is called after setOutputFormat()
468     * @see android.media.MediaRecorder.VideoSource
469     */
470    public native void setVideoSource(int video_source)
471            throws IllegalStateException;
472
473    /**
474     * Uses the settings from a CamcorderProfile object for recording. This method should
475     * be called after the video AND audio sources are set, and before setOutputFile().
476     * If a time lapse CamcorderProfile is used, audio related source or recording
477     * parameters are ignored.
478     *
479     * @param profile the CamcorderProfile to use
480     * @see android.media.CamcorderProfile
481     */
482    public void setProfile(CamcorderProfile profile) {
483        setOutputFormat(profile.fileFormat);
484        setVideoFrameRate(profile.videoFrameRate);
485        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
486        setVideoEncodingBitRate(profile.videoBitRate);
487        setVideoEncoder(profile.videoCodec);
488        if (profile.quality >= CamcorderProfile.QUALITY_TIME_LAPSE_LOW &&
489             profile.quality <= CamcorderProfile.QUALITY_TIME_LAPSE_QVGA) {
490            // Nothing needs to be done. Call to setCaptureRate() enables
491            // time lapse video recording.
492        } else {
493            setAudioEncodingBitRate(profile.audioBitRate);
494            setAudioChannels(profile.audioChannels);
495            setAudioSamplingRate(profile.audioSampleRate);
496            setAudioEncoder(profile.audioCodec);
497        }
498    }
499
500    /**
501     * Set video frame capture rate. This can be used to set a different video frame capture
502     * rate than the recorded video's playback rate. This method also sets the recording mode
503     * to time lapse. In time lapse video recording, only video is recorded. Audio related
504     * parameters are ignored when a time lapse recording session starts, if an application
505     * sets them.
506     *
507     * @param fps Rate at which frames should be captured in frames per second.
508     * The fps can go as low as desired. However the fastest fps will be limited by the hardware.
509     * For resolutions that can be captured by the video camera, the fastest fps can be computed using
510     * {@link android.hardware.Camera.Parameters#getPreviewFpsRange(int[])}. For higher
511     * resolutions the fastest fps may be more restrictive.
512     * Note that the recorder cannot guarantee that frames will be captured at the
513     * given rate due to camera/encoder limitations. However it tries to be as close as
514     * possible.
515     */
516    public void setCaptureRate(double fps) {
517        // Make sure that time lapse is enabled when this method is called.
518        setParameter("time-lapse-enable=1");
519        setParameter("time-lapse-fps=" + fps);
520    }
521
522    /**
523     * Sets the orientation hint for output video playback.
524     * This method should be called before prepare(). This method will not
525     * trigger the source video frame to rotate during video recording, but to
526     * add a composition matrix containing the rotation angle in the output
527     * video if the output format is OutputFormat.THREE_GPP or
528     * OutputFormat.MPEG_4 so that a video player can choose the proper
529     * orientation for playback. Note that some video players may choose
530     * to ignore the compostion matrix in a video during playback.
531     *
532     * @param degrees the angle to be rotated clockwise in degrees.
533     * The supported angles are 0, 90, 180, and 270 degrees.
534     * @throws IllegalArgumentException if the angle is not supported.
535     *
536     */
537    public void setOrientationHint(int degrees) {
538        if (degrees != 0   &&
539            degrees != 90  &&
540            degrees != 180 &&
541            degrees != 270) {
542            throw new IllegalArgumentException("Unsupported angle: " + degrees);
543        }
544        setParameter("video-param-rotation-angle-degrees=" + degrees);
545    }
546
547    /**
548     * Set and store the geodata (latitude and longitude) in the output file.
549     * This method should be called before prepare(). The geodata is
550     * stored in udta box if the output format is OutputFormat.THREE_GPP
551     * or OutputFormat.MPEG_4, and is ignored for other output formats.
552     * The geodata is stored according to ISO-6709 standard.
553     *
554     * @param latitude latitude in degrees. Its value must be in the
555     * range [-90, 90].
556     * @param longitude longitude in degrees. Its value must be in the
557     * range [-180, 180].
558     *
559     * @throws IllegalArgumentException if the given latitude or
560     * longitude is out of range.
561     *
562     */
563    public void setLocation(float latitude, float longitude) {
564        int latitudex10000  = (int) (latitude * 10000 + 0.5);
565        int longitudex10000 = (int) (longitude * 10000 + 0.5);
566
567        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
568            String msg = "Latitude: " + latitude + " out of range.";
569            throw new IllegalArgumentException(msg);
570        }
571        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
572            String msg = "Longitude: " + longitude + " out of range";
573            throw new IllegalArgumentException(msg);
574        }
575
576        setParameter("param-geotag-latitude=" + latitudex10000);
577        setParameter("param-geotag-longitude=" + longitudex10000);
578    }
579
580    /**
581     * Sets the format of the output file produced during recording. Call this
582     * after setAudioSource()/setVideoSource() but before prepare().
583     *
584     * <p>It is recommended to always use 3GP format when using the H.263
585     * video encoder and AMR audio encoder. Using an MPEG-4 container format
586     * may confuse some desktop players.</p>
587     *
588     * @param output_format the output format to use. The output format
589     * needs to be specified before setting recording-parameters or encoders.
590     * @throws IllegalStateException if it is called after prepare() or before
591     * setAudioSource()/setVideoSource().
592     * @see android.media.MediaRecorder.OutputFormat
593     */
594    public native void setOutputFormat(int output_format)
595            throws IllegalStateException;
596
597    /**
598     * Sets the width and height of the video to be captured.  Must be called
599     * after setVideoSource(). Call this after setOutFormat() but before
600     * prepare().
601     *
602     * @param width the width of the video to be captured
603     * @param height the height of the video to be captured
604     * @throws IllegalStateException if it is called after
605     * prepare() or before setOutputFormat()
606     */
607    public native void setVideoSize(int width, int height)
608            throws IllegalStateException;
609
610    /**
611     * Sets the frame rate of the video to be captured.  Must be called
612     * after setVideoSource(). Call this after setOutFormat() but before
613     * prepare().
614     *
615     * @param rate the number of frames per second of video to capture
616     * @throws IllegalStateException if it is called after
617     * prepare() or before setOutputFormat().
618     *
619     * NOTE: On some devices that have auto-frame rate, this sets the
620     * maximum frame rate, not a constant frame rate. Actual frame rate
621     * will vary according to lighting conditions.
622     */
623    public native void setVideoFrameRate(int rate) throws IllegalStateException;
624
625    /**
626     * Sets the maximum duration (in ms) of the recording session.
627     * Call this after setOutFormat() but before prepare().
628     * After recording reaches the specified duration, a notification
629     * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
630     * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
631     * and recording will be stopped. Stopping happens asynchronously, there
632     * is no guarantee that the recorder will have stopped by the time the
633     * listener is notified.
634     *
635     * @param max_duration_ms the maximum duration in ms (if zero or negative, disables the duration limit)
636     *
637     */
638    public native void setMaxDuration(int max_duration_ms) throws IllegalArgumentException;
639
640    /**
641     * Sets the maximum filesize (in bytes) of the recording session.
642     * Call this after setOutFormat() but before prepare().
643     * After recording reaches the specified filesize, a notification
644     * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
645     * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
646     * and recording will be stopped. Stopping happens asynchronously, there
647     * is no guarantee that the recorder will have stopped by the time the
648     * listener is notified.
649     *
650     * @param max_filesize_bytes the maximum filesize in bytes (if zero or negative, disables the limit)
651     *
652     */
653    public native void setMaxFileSize(long max_filesize_bytes) throws IllegalArgumentException;
654
655    /**
656     * Sets the audio encoder to be used for recording. If this method is not
657     * called, the output file will not contain an audio track. Call this after
658     * setOutputFormat() but before prepare().
659     *
660     * @param audio_encoder the audio encoder to use.
661     * @throws IllegalStateException if it is called before
662     * setOutputFormat() or after prepare().
663     * @see android.media.MediaRecorder.AudioEncoder
664     */
665    public native void setAudioEncoder(int audio_encoder)
666            throws IllegalStateException;
667
668    /**
669     * Sets the video encoder to be used for recording. If this method is not
670     * called, the output file will not contain an video track. Call this after
671     * setOutputFormat() and before prepare().
672     *
673     * @param video_encoder the video encoder to use.
674     * @throws IllegalStateException if it is called before
675     * setOutputFormat() or after prepare()
676     * @see android.media.MediaRecorder.VideoEncoder
677     */
678    public native void setVideoEncoder(int video_encoder)
679            throws IllegalStateException;
680
681    /**
682     * Sets the audio sampling rate for recording. Call this method before prepare().
683     * Prepare() may perform additional checks on the parameter to make sure whether
684     * the specified audio sampling rate is applicable. The sampling rate really depends
685     * on the format for the audio recording, as well as the capabilities of the platform.
686     * For instance, the sampling rate supported by AAC audio coding standard ranges
687     * from 8 to 96 kHz, the sampling rate supported by AMRNB is 8kHz, and the sampling
688     * rate supported by AMRWB is 16kHz. Please consult with the related audio coding
689     * standard for the supported audio sampling rate.
690     *
691     * @param samplingRate the sampling rate for audio in samples per second.
692     */
693    public void setAudioSamplingRate(int samplingRate) {
694        if (samplingRate <= 0) {
695            throw new IllegalArgumentException("Audio sampling rate is not positive");
696        }
697        setParameter("audio-param-sampling-rate=" + samplingRate);
698    }
699
700    /**
701     * Sets the number of audio channels for recording. Call this method before prepare().
702     * Prepare() may perform additional checks on the parameter to make sure whether the
703     * specified number of audio channels are applicable.
704     *
705     * @param numChannels the number of audio channels. Usually it is either 1 (mono) or 2
706     * (stereo).
707     */
708    public void setAudioChannels(int numChannels) {
709        if (numChannels <= 0) {
710            throw new IllegalArgumentException("Number of channels is not positive");
711        }
712        setParameter("audio-param-number-of-channels=" + numChannels);
713    }
714
715    /**
716     * Sets the audio encoding bit rate for recording. Call this method before prepare().
717     * Prepare() may perform additional checks on the parameter to make sure whether the
718     * specified bit rate is applicable, and sometimes the passed bitRate will be clipped
719     * internally to ensure the audio recording can proceed smoothly based on the
720     * capabilities of the platform.
721     *
722     * @param bitRate the audio encoding bit rate in bits per second.
723     */
724    public void setAudioEncodingBitRate(int bitRate) {
725        if (bitRate <= 0) {
726            throw new IllegalArgumentException("Audio encoding bit rate is not positive");
727        }
728        setParameter("audio-param-encoding-bitrate=" + bitRate);
729    }
730
731    /**
732     * Sets the video encoding bit rate for recording. Call this method before prepare().
733     * Prepare() may perform additional checks on the parameter to make sure whether the
734     * specified bit rate is applicable, and sometimes the passed bitRate will be
735     * clipped internally to ensure the video recording can proceed smoothly based on
736     * the capabilities of the platform.
737     *
738     * @param bitRate the video encoding bit rate in bits per second.
739     */
740    public void setVideoEncodingBitRate(int bitRate) {
741        if (bitRate <= 0) {
742            throw new IllegalArgumentException("Video encoding bit rate is not positive");
743        }
744        setParameter("video-param-encoding-bitrate=" + bitRate);
745    }
746
747    /**
748     * Sets the video encoding profile for recording. Call this method before prepare().
749     * Prepare() may perform additional checks on the parameter to make sure whether the
750     * specified profile and level are applicable, and sometimes the passed profile or
751     * level will be discarded due to codec capablity or to ensure the video recording
752     * can proceed smoothly based on the capabilities of the platform.
753     * @hide
754     * @param profile declared in {@link MediaCodecInfo.CodecProfileLevel}.
755     * @param level declared in {@link MediaCodecInfo.CodecProfileLevel}.
756     */
757    public void setVideoEncodingProfileLevel(int profile, int level) {
758        if (profile <= 0)  {
759            throw new IllegalArgumentException("Video encoding profile is not positive");
760        }
761        if (level <= 0)  {
762            throw new IllegalArgumentException("Video encoding level is not positive");
763        }
764        setParameter("video-param-encoder-profile=" + profile);
765        setParameter("video-param-encoder-level=" + level);
766    }
767
768    /**
769     * Currently not implemented. It does nothing.
770     * @deprecated Time lapse mode video recording using camera still image capture
771     * is not desirable, and will not be supported.
772     * @hide
773     */
774    public void setAuxiliaryOutputFile(FileDescriptor fd)
775    {
776        Log.w(TAG, "setAuxiliaryOutputFile(FileDescriptor) is no longer supported.");
777    }
778
779    /**
780     * Currently not implemented. It does nothing.
781     * @deprecated Time lapse mode video recording using camera still image capture
782     * is not desirable, and will not be supported.
783     * @hide
784     */
785    public void setAuxiliaryOutputFile(String path)
786    {
787        Log.w(TAG, "setAuxiliaryOutputFile(String) is no longer supported.");
788    }
789
790    /**
791     * Pass in the file descriptor of the file to be written. Call this after
792     * setOutputFormat() but before prepare().
793     *
794     * @param fd an open file descriptor to be written into.
795     * @throws IllegalStateException if it is called before
796     * setOutputFormat() or after prepare()
797     */
798    public void setOutputFile(FileDescriptor fd) throws IllegalStateException
799    {
800        mPath = null;
801        mFd = fd;
802    }
803
804    /**
805     * Sets the next output file descriptor to be used when the maximum filesize is reached
806     * on the prior output {@link #setOutputFile} or {@link #setNextOutputFile}). File descriptor
807     * must be seekable and writable. After setting the next output file, application should not
808     * use the file referenced by this file descriptor until {@link #stop}. It is the application's
809     * responsibility to close the file descriptor. It is safe to do so as soon as this call returns.
810     * Application must call this after receiving on the
811     * {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
812     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING} and before receiving a "what" code of
813     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}. The file is not used until switching to
814     * that output. Application will receive{@link #MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED}
815     * when the next output file is used. Application will not be able to set a new output file if
816     * the previous one has not been used. Application is responsible for cleaning up unused files
817     * after {@link #stop} is called.
818     *
819     * @param fd an open file descriptor to be written into.
820     * @throws IllegalStateException if it is called before prepare().
821     * @throws IOException if setNextOutputFile fails otherwise.
822     */
823    public void setNextOutputFile(FileDescriptor fd) throws IllegalStateException, IOException
824    {
825        _setNextOutputFile(fd);
826    }
827
828    /**
829     * Sets the path of the output file to be produced. Call this after
830     * setOutputFormat() but before prepare().
831     *
832     * @param path The pathname to use.
833     * @throws IllegalStateException if it is called before
834     * setOutputFormat() or after prepare()
835     */
836    public void setOutputFile(String path) throws IllegalStateException
837    {
838        mFd = null;
839        mPath = path;
840    }
841
842    /**
843     * Sets the next output file path to be used when the maximum filesize is reached
844     * on the prior output {@link #setOutputFile} or {@link #setNextOutputFile}). File should
845     * be seekable. After setting the next output file, application should not use the file
846     * referenced by this file descriptor until {@link #stop}. Application must call this
847     * after receiving on the {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
848     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING} and before receiving a "what" code of
849     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}. The file is not used until switching to
850     * that output. Application will receive {@link #MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED}
851     * when the next output file is used. Application will not be able to set a new output file if
852     * the previous one has not been used. Application is responsible for cleaning up unused files
853     * after {@link #stop} is called.
854     *
855     * @param  path The pathname to use.
856     * @throws IllegalStateException if it is called before prepare().
857     * @throws IOException if setNextOutputFile fails otherwise.
858     */
859    public void setNextOutputFile(String path) throws IllegalStateException, IOException
860    {
861        if (path != null) {
862            RandomAccessFile file = new RandomAccessFile(path, "rws");
863            try {
864                _setNextOutputFile(file.getFD());
865            } finally {
866                file.close();
867            }
868        }
869    }
870
871    // native implementation
872    private native void _setOutputFile(FileDescriptor fd) throws IllegalStateException, IOException;
873    private native void _setNextOutputFile(FileDescriptor fd) throws IllegalStateException, IOException;
874    private native void _prepare() throws IllegalStateException, IOException;
875
876    /**
877     * Prepares the recorder to begin capturing and encoding data. This method
878     * must be called after setting up the desired audio and video sources,
879     * encoders, file format, etc., but before start().
880     *
881     * @throws IllegalStateException if it is called after
882     * start() or before setOutputFormat().
883     * @throws IOException if prepare fails otherwise.
884     */
885    public void prepare() throws IllegalStateException, IOException
886    {
887        if (mPath != null) {
888            RandomAccessFile file = new RandomAccessFile(mPath, "rws");
889            try {
890                _setOutputFile(file.getFD());
891            } finally {
892                file.close();
893            }
894        } else if (mFd != null) {
895            _setOutputFile(mFd);
896        } else {
897            throw new IOException("No valid output file");
898        }
899
900        _prepare();
901    }
902
903    /**
904     * Begins capturing and encoding data to the file specified with
905     * setOutputFile(). Call this after prepare().
906     *
907     * <p>Since API level 13, if applications set a camera via
908     * {@link #setCamera(Camera)}, the apps can use the camera after this method
909     * call. The apps do not need to lock the camera again. However, if this
910     * method fails, the apps should still lock the camera back. The apps should
911     * not start another recording session during recording.
912     *
913     * @throws IllegalStateException if it is called before
914     * prepare().
915     */
916    public native void start() throws IllegalStateException;
917
918    /**
919     * Stops recording. Call this after start(). Once recording is stopped,
920     * you will have to configure it again as if it has just been constructed.
921     * Note that a RuntimeException is intentionally thrown to the
922     * application, if no valid audio/video data has been received when stop()
923     * is called. This happens if stop() is called immediately after
924     * start(). The failure lets the application take action accordingly to
925     * clean up the output file (delete the output file, for instance), since
926     * the output file is not properly constructed when this happens.
927     *
928     * @throws IllegalStateException if it is called before start()
929     */
930    public native void stop() throws IllegalStateException;
931
932    /**
933     * Pauses recording. Call this after start(). You may resume recording
934     * with resume() without reconfiguration, as opposed to stop(). It does
935     * nothing if the recording is already paused.
936     *
937     * When the recording is paused and resumed, the resulting output would
938     * be as if nothing happend during paused period, immediately switching
939     * to the resumed scene.
940     *
941     * @throws IllegalStateException if it is called before start() or after
942     * stop()
943     */
944    public native void pause() throws IllegalStateException;
945
946    /**
947     * Resumes recording. Call this after start(). It does nothing if the
948     * recording is not paused.
949     *
950     * @throws IllegalStateException if it is called before start() or after
951     * stop()
952     * @see android.media.MediaRecorder#pause
953     */
954    public native void resume() throws IllegalStateException;
955
956    /**
957     * Restarts the MediaRecorder to its idle state. After calling
958     * this method, you will have to configure it again as if it had just been
959     * constructed.
960     */
961    public void reset() {
962        native_reset();
963
964        // make sure none of the listeners get called anymore
965        mEventHandler.removeCallbacksAndMessages(null);
966    }
967
968    private native void native_reset();
969
970    /**
971     * Returns the maximum absolute amplitude that was sampled since the last
972     * call to this method. Call this only after the setAudioSource().
973     *
974     * @return the maximum absolute amplitude measured since the last call, or
975     * 0 when called for the first time
976     * @throws IllegalStateException if it is called before
977     * the audio source has been set.
978     */
979    public native int getMaxAmplitude() throws IllegalStateException;
980
981    /* Do not change this value without updating its counterpart
982     * in include/media/mediarecorder.h or mediaplayer.h!
983     */
984    /** Unspecified media recorder error.
985     * @see android.media.MediaRecorder.OnErrorListener
986     */
987    public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1;
988    /** Media server died. In this case, the application must release the
989     * MediaRecorder object and instantiate a new one.
990     * @see android.media.MediaRecorder.OnErrorListener
991     */
992    public static final int MEDIA_ERROR_SERVER_DIED = 100;
993
994    /**
995     * Interface definition for a callback to be invoked when an error
996     * occurs while recording.
997     */
998    public interface OnErrorListener
999    {
1000        /**
1001         * Called when an error occurs while recording.
1002         *
1003         * @param mr the MediaRecorder that encountered the error
1004         * @param what    the type of error that has occurred:
1005         * <ul>
1006         * <li>{@link #MEDIA_RECORDER_ERROR_UNKNOWN}
1007         * <li>{@link #MEDIA_ERROR_SERVER_DIED}
1008         * </ul>
1009         * @param extra   an extra code, specific to the error type
1010         */
1011        void onError(MediaRecorder mr, int what, int extra);
1012    }
1013
1014    /**
1015     * Register a callback to be invoked when an error occurs while
1016     * recording.
1017     *
1018     * @param l the callback that will be run
1019     */
1020    public void setOnErrorListener(OnErrorListener l)
1021    {
1022        mOnErrorListener = l;
1023    }
1024
1025    /* Do not change these values without updating their counterparts
1026     * in include/media/mediarecorder.h!
1027     */
1028    /** Unspecified media recorder info.
1029     * @see android.media.MediaRecorder.OnInfoListener
1030     */
1031    public static final int MEDIA_RECORDER_INFO_UNKNOWN              = 1;
1032    /** A maximum duration had been setup and has now been reached.
1033     * @see android.media.MediaRecorder.OnInfoListener
1034     */
1035    public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800;
1036    /** A maximum filesize had been setup and has now been reached.
1037     * Note: This event will not be sent if application already set
1038     * next output file through {@link #setNextOutputFile}.
1039     * @see android.media.MediaRecorder.OnInfoListener
1040     */
1041    public static final int MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801;
1042    /** A maximum filesize had been setup and current recorded file size
1043     * has reached 90% of the limit. This is sent once per file upon
1044     * reaching/passing the 90% limit. To continue the recording, applicaiton
1045     * should use {@link #setNextOutputFile} to set the next output file.
1046     * Otherwise, recording will stop when reaching maximum file size.
1047     * @see android.media.MediaRecorder.OnInfoListener
1048     */
1049    public static final int MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING = 802;
1050    /** A maximum filesize had been reached and MediaRecorder has switched
1051     * output to a new file set by application {@link #setNextOutputFile}.
1052     * For best practice, application should use this event to keep track
1053     * of whether the file previously set has been used or not.
1054     * @see android.media.MediaRecorder.OnInfoListener
1055     */
1056    public static final int MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED = 803;
1057
1058    /** informational events for individual tracks, for testing purpose.
1059     * The track informational event usually contains two parts in the ext1
1060     * arg of the onInfo() callback: bit 31-28 contains the track id; and
1061     * the rest of the 28 bits contains the informational event defined here.
1062     * For example, ext1 = (1 << 28 | MEDIA_RECORDER_TRACK_INFO_TYPE) if the
1063     * track id is 1 for informational event MEDIA_RECORDER_TRACK_INFO_TYPE;
1064     * while ext1 = (0 << 28 | MEDIA_RECORDER_TRACK_INFO_TYPE) if the track
1065     * id is 0 for informational event MEDIA_RECORDER_TRACK_INFO_TYPE. The
1066     * application should extract the track id and the type of informational
1067     * event from ext1, accordingly.
1068     *
1069     * FIXME:
1070     * Please update the comment for onInfo also when these
1071     * events are unhidden so that application knows how to extract the track
1072     * id and the informational event type from onInfo callback.
1073     *
1074     * {@hide}
1075     */
1076    public static final int MEDIA_RECORDER_TRACK_INFO_LIST_START        = 1000;
1077    /** Signal the completion of the track for the recording session.
1078     * {@hide}
1079     */
1080    public static final int MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS = 1000;
1081    /** Indicate the recording progress in time (ms) during recording.
1082     * {@hide}
1083     */
1084    public static final int MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME  = 1001;
1085    /** Indicate the track type: 0 for Audio and 1 for Video.
1086     * {@hide}
1087     */
1088    public static final int MEDIA_RECORDER_TRACK_INFO_TYPE              = 1002;
1089    /** Provide the track duration information.
1090     * {@hide}
1091     */
1092    public static final int MEDIA_RECORDER_TRACK_INFO_DURATION_MS       = 1003;
1093    /** Provide the max chunk duration in time (ms) for the given track.
1094     * {@hide}
1095     */
1096    public static final int MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS  = 1004;
1097    /** Provide the total number of recordd frames.
1098     * {@hide}
1099     */
1100    public static final int MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES    = 1005;
1101    /** Provide the max spacing between neighboring chunks for the given track.
1102     * {@hide}
1103     */
1104    public static final int MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS    = 1006;
1105    /** Provide the elapsed time measuring from the start of the recording
1106     * till the first output frame of the given track is received, excluding
1107     * any intentional start time offset of a recording session for the
1108     * purpose of eliminating the recording sound in the recorded file.
1109     * {@hide}
1110     */
1111    public static final int MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS  = 1007;
1112    /** Provide the start time difference (delay) betweeen this track and
1113     * the start of the movie.
1114     * {@hide}
1115     */
1116    public static final int MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS   = 1008;
1117    /** Provide the total number of data (in kilo-bytes) encoded.
1118     * {@hide}
1119     */
1120    public static final int MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES       = 1009;
1121    /**
1122     * {@hide}
1123     */
1124    public static final int MEDIA_RECORDER_TRACK_INFO_LIST_END          = 2000;
1125
1126
1127    /**
1128     * Interface definition of a callback to be invoked to communicate some
1129     * info and/or warning about the recording.
1130     */
1131    public interface OnInfoListener
1132    {
1133        /**
1134         * Called to indicate an info or a warning during recording.
1135         *
1136         * @param mr   the MediaRecorder the info pertains to
1137         * @param what the type of info or warning that has occurred
1138         * <ul>
1139         * <li>{@link #MEDIA_RECORDER_INFO_UNKNOWN}
1140         * <li>{@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
1141         * <li>{@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
1142         * </ul>
1143         * @param extra   an extra code, specific to the info type
1144         */
1145        void onInfo(MediaRecorder mr, int what, int extra);
1146    }
1147
1148    /**
1149     * Register a callback to be invoked when an informational event occurs while
1150     * recording.
1151     *
1152     * @param listener the callback that will be run
1153     */
1154    public void setOnInfoListener(OnInfoListener listener)
1155    {
1156        mOnInfoListener = listener;
1157    }
1158
1159    private class EventHandler extends Handler
1160    {
1161        private MediaRecorder mMediaRecorder;
1162
1163        public EventHandler(MediaRecorder mr, Looper looper) {
1164            super(looper);
1165            mMediaRecorder = mr;
1166        }
1167
1168        /* Do not change these values without updating their counterparts
1169         * in include/media/mediarecorder.h!
1170         */
1171        private static final int MEDIA_RECORDER_EVENT_LIST_START = 1;
1172        private static final int MEDIA_RECORDER_EVENT_ERROR      = 1;
1173        private static final int MEDIA_RECORDER_EVENT_INFO       = 2;
1174        private static final int MEDIA_RECORDER_EVENT_LIST_END   = 99;
1175
1176        /* Events related to individual tracks */
1177        private static final int MEDIA_RECORDER_TRACK_EVENT_LIST_START = 100;
1178        private static final int MEDIA_RECORDER_TRACK_EVENT_ERROR      = 100;
1179        private static final int MEDIA_RECORDER_TRACK_EVENT_INFO       = 101;
1180        private static final int MEDIA_RECORDER_TRACK_EVENT_LIST_END   = 1000;
1181
1182
1183        @Override
1184        public void handleMessage(Message msg) {
1185            if (mMediaRecorder.mNativeContext == 0) {
1186                Log.w(TAG, "mediarecorder went away with unhandled events");
1187                return;
1188            }
1189            switch(msg.what) {
1190            case MEDIA_RECORDER_EVENT_ERROR:
1191            case MEDIA_RECORDER_TRACK_EVENT_ERROR:
1192                if (mOnErrorListener != null)
1193                    mOnErrorListener.onError(mMediaRecorder, msg.arg1, msg.arg2);
1194
1195                return;
1196
1197            case MEDIA_RECORDER_EVENT_INFO:
1198            case MEDIA_RECORDER_TRACK_EVENT_INFO:
1199                if (mOnInfoListener != null)
1200                    mOnInfoListener.onInfo(mMediaRecorder, msg.arg1, msg.arg2);
1201
1202                return;
1203
1204            default:
1205                Log.e(TAG, "Unknown message type " + msg.what);
1206                return;
1207            }
1208        }
1209    }
1210
1211    /**
1212     * Called from native code when an interesting event happens.  This method
1213     * just uses the EventHandler system to post the event back to the main app thread.
1214     * We use a weak reference to the original MediaRecorder object so that the native
1215     * code is safe from the object disappearing from underneath it.  (This is
1216     * the cookie passed to native_setup().)
1217     */
1218    private static void postEventFromNative(Object mediarecorder_ref,
1219                                            int what, int arg1, int arg2, Object obj)
1220    {
1221        MediaRecorder mr = (MediaRecorder)((WeakReference)mediarecorder_ref).get();
1222        if (mr == null) {
1223            return;
1224        }
1225
1226        if (mr.mEventHandler != null) {
1227            Message m = mr.mEventHandler.obtainMessage(what, arg1, arg2, obj);
1228            mr.mEventHandler.sendMessage(m);
1229        }
1230    }
1231
1232    /**
1233     * Releases resources associated with this MediaRecorder object.
1234     * It is good practice to call this method when you're done
1235     * using the MediaRecorder. In particular, whenever an Activity
1236     * of an application is paused (its onPause() method is called),
1237     * or stopped (its onStop() method is called), this method should be
1238     * invoked to release the MediaRecorder object, unless the application
1239     * has a special need to keep the object around. In addition to
1240     * unnecessary resources (such as memory and instances of codecs)
1241     * being held, failure to call this method immediately if a
1242     * MediaRecorder object is no longer needed may also lead to
1243     * continuous battery consumption for mobile devices, and recording
1244     * failure for other applications if no multiple instances of the
1245     * same codec are supported on a device. Even if multiple instances
1246     * of the same codec are supported, some performance degradation
1247     * may be expected when unnecessary multiple instances are used
1248     * at the same time.
1249     */
1250    public native void release();
1251
1252    private static native final void native_init();
1253
1254    private native final void native_setup(Object mediarecorder_this,
1255            String clientName, String opPackageName) throws IllegalStateException;
1256
1257    private native final void native_finalize();
1258
1259    private native void setParameter(String nameValuePair);
1260
1261    /**
1262     * Returns Metrics data about the current media container.
1263     *
1264     * @return the set of keys and values available for the media being
1265     * handled by this instance of MediaExtractor. The keys, data types,
1266     * and meaning are described in the following table.
1267     *
1268     *  <table style="width: 0%">
1269     *   <thead>
1270     *    <tr>
1271     *     <th>Key</th>
1272     *     <th>Type</th>
1273     *     <th>Description</th>
1274     *    </tr>
1275     *   </thead>
1276     *   <tbody>
1277     *    <tr>
1278     *     <td>{@code "ht"}</td>
1279     *     <td>Integer</td>
1280     *     <td>Height of the recorded video (pixels)</td>
1281     *    </tr><tr>
1282     *     <td>{@code "wid"}</td>
1283     *     <td>Integer</td>
1284     *     <td>Width of the recorded video (pixels)</td>
1285     *    </tr><tr>
1286     *     <td>{@code "frame-rate"}</td>
1287     *     <td>Integer</td>
1288     *     <td>Framerate of captured Video (frames per second)</td>
1289     *    </tr><tr>
1290     *     <td>{@code "video-bitrate"}</td>
1291     *     <td>Integer</td>
1292     *     <td>Bit rate of encoded video (bits per second)</td>
1293     *    </tr><tr>
1294     *     <td>{@code "video-iframe-interval"}</td>
1295     *     <td>Integer</td>
1296     *     <td>Interval between encoded IFrames (seconds)</td>
1297     *    </tr><tr>
1298     *     <td>{@code "video-timescale"}</td>
1299     *     <td>Integer</td>
1300     *     <td></td>
1301     *    </tr><tr>
1302     *     <td>{@code "video-encoder-profile"}</td>
1303     *     <td>Integer</td>
1304     *     <td>Video Encoder Profile, as defined in OpenMAX IL</td>
1305     *    </tr><tr>
1306     *     <td>{@code "video-encoder-level"}</td>
1307     *     <td>Integer</td>
1308     *     <td>Video Encoder Level, as defined in OpenMAX IL</td>
1309     *    </tr><tr>
1310     *     <td>{@code "audio-bitrate"}</td>
1311     *     <td>Integer</td>
1312     *     <td>Bitrate of encoded audio (bits per second)</td>
1313     *    </tr><tr>
1314     *     <td>{@code "audio-samplerate"}</td>
1315     *     <td>Integer</td>
1316     *     <td></td>
1317     *    </tr><tr>
1318     *     <td>{@code "audio-channels"}</td>
1319     *     <td>Integer</td>
1320     *     <td>Number of Audio Channels Captured</td>
1321     *    </tr><tr>
1322     *     <td>{@code "audio-timescale"}</td>
1323     *     <td>Integer</td>
1324     *     <td></td>
1325     *    </tr><tr>
1326     *     <td>{@code "movie-timescale"}</td>
1327     *     <td>Integer</td>
1328     *     <td></td>
1329     *    </tr><tr>
1330     *     <td>{@code "movie-timescale"}</td>
1331     *     <td>Integer</td>
1332     *     <td></td>
1333     *    </tr><tr>
1334     *     <td>{@code "capture-fps"}</td>
1335     *     <td>Integer</td>
1336     *     <td></td>
1337     *    </tr><tr>
1338     *     <td>{@code "rotation"}</td>
1339     *     <td>Integer</td>
1340     *     <td>Orientation of the Video (degrees)</td>
1341     *    </tr>
1342     *   </tbody>
1343     *  </table>
1344     */
1345
1346    public native Bundle getMetrics();
1347
1348    @Override
1349    protected void finalize() { native_finalize(); }
1350}
1351