MediaRecorder.java revision 076357b8567458d4b6dfdcf839ef751634cd2bfb
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.view.Surface;
20import android.hardware.Camera;
21import java.io.IOException;
22import java.io.FileNotFoundException;
23import java.io.FileOutputStream;
24import java.io.FileDescriptor;
25import android.util.Log;
26
27/**
28 * Used to record audio and video. The recording control is based on a
29 * simple state machine (see below).
30 *
31 * <p><img src="{@docRoot}images/mediarecorder_state_diagram.gif" border="0" />
32 * </p>
33 *
34 * <p>A common case of using MediaRecorder to record audio works as follows:
35 *
36 * <pre>MediaRecorder recorder = new MediaRecorder();
37 * recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
38 * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
39 * recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
40 * recorder.setOutputFile(PATH_NAME);
41 * recorder.prepare();
42 * recorder.start();   // Recording is now started
43 * ...
44 * recorder.stop();
45 * recorder.reset();   // You can reuse the object by going back to setAudioSource() step
46 * recorder.release(); // Now the object cannot be reused
47 * </pre>
48 *
49 * <p>See the <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a>
50 * documentation for additional help with using MediaRecorder.
51 */
52public class MediaRecorder
53{
54    static {
55        System.loadLibrary("media_jni");
56    }
57    private final static String TAG = "MediaRecorder";
58
59    // The two fields below are accessed by native methods
60    @SuppressWarnings("unused")
61    private int mNativeContext;
62
63    @SuppressWarnings("unused")
64    private Surface mSurface;
65
66    private String mPath;
67    private FileDescriptor mFd;
68
69    /**
70     * Default constructor.
71     */
72    public MediaRecorder() {
73        native_setup();
74    }
75
76    /**
77     * Sets a Camera to use for recording. Use this function to switch
78     * quickly between preview and capture mode without a teardown of
79     * the camera object. Must call before prepare().
80     *
81     * @param c the Camera to use for recording
82     */
83    public native void setCamera(Camera c);
84
85    /**
86     * Sets a Surface to show a preview of recorded media (video). Calls this
87     * before prepare() to make sure that the desirable preview display is
88     * set.
89     *
90     * @param sv the Surface to use for the preview
91     */
92    public void setPreviewDisplay(Surface sv) {
93        mSurface = sv;
94    }
95
96    /**
97     * Defines the audio source. These constants are used with
98     * {@link MediaRecorder#setAudioSource(int)}.
99     */
100    public final class AudioSource {
101      /* Do not change these values without updating their counterparts
102       * in include/media/mediarecorder.h!
103       */
104        private AudioSource() {}
105        public static final int DEFAULT = 0;
106        /** Microphone audio source */
107        public static final int MIC = 1;
108    }
109
110    /**
111     * Defines the video source. These constants are used with
112     * {@link MediaRecorder#setVideoSource(int)}.
113     */
114    public final class VideoSource {
115      /* Do not change these values without updating their counterparts
116       * in include/media/mediarecorder.h!
117       */
118        private VideoSource() {}
119        public static final int DEFAULT = 0;
120        /** Camera video source */
121        public static final int CAMERA = 1;
122    }
123
124    /**
125     * Defines the output format. These constants are used with
126     * {@link MediaRecorder#setOutputFormat(int)}.
127     */
128    public final class OutputFormat {
129      /* Do not change these values without updating their counterparts
130       * in include/media/mediarecorder.h!
131       */
132        private OutputFormat() {}
133        public static final int DEFAULT = 0;
134        /** 3GPP media file format*/
135        public static final int THREE_GPP = 1;
136        /** MPEG4 media file format*/
137        public static final int MPEG_4 = 2;
138        /** Raw AMR file format */
139        public static final int RAW_AMR = 3;
140    };
141
142    /**
143     * Defines the audio encoding. These constants are used with
144     * {@link MediaRecorder#setAudioEncoder(int)}.
145     */
146    public final class AudioEncoder {
147      /* Do not change these values without updating their counterparts
148       * in include/media/mediarecorder.h!
149       */
150        private AudioEncoder() {}
151        public static final int DEFAULT = 0;
152        /** AMR (Narrowband) audio codec */
153        public static final int AMR_NB = 1;
154        //public static final AAC = 2;  currently unsupported
155    }
156
157    /**
158     * Defines the video encoding. These constants are used with
159     * {@link MediaRecorder#setVideoEncoder(int)}.
160     */
161    public final class VideoEncoder {
162      /* Do not change these values without updating their counterparts
163       * in include/media/mediarecorder.h!
164       */
165        private VideoEncoder() {}
166        public static final int DEFAULT = 0;
167        public static final int H263 = 1;
168        public static final int H264 = 2;
169        public static final int MPEG_4_SP = 3;
170    }
171
172    /**
173     * Sets the audio source to be used for recording. If this method is not
174     * called, the output file will not contain an audio track. The source needs
175     * to be specified before setting recording-parameters or encoders. Call
176     * this only before setOutputFormat().
177     *
178     * @param audio_source the audio source to use
179     * @throws IllegalStateException if it is called after setOutputFormat()
180     * @see android.media.MediaRecorder.AudioSource
181     */
182    public native void setAudioSource(int audio_source)
183            throws IllegalStateException;
184
185    /**
186     * Sets the video source to be used for recording. If this method is not
187     * called, the output file will not contain an video track. The source needs
188     * to be specified before setting recording-parameters or encoders. Call
189     * this only before setOutputFormat().
190     *
191     * @param video_source the video source to use
192     * @throws IllegalStateException if it is called after setOutputFormat()
193     * @see android.media.MediaRecorder.VideoSource
194     */
195    public native void setVideoSource(int video_source)
196            throws IllegalStateException;
197
198    /**
199     * Sets the format of the output file produced during recording. Call this
200     * after setAudioSource()/setVideoSource() but before prepare().
201     *
202     * @param output_format the output format to use. The output format
203     * needs to be specified before setting recording-parameters or encoders.
204     * @throws IllegalStateException if it is called after prepare() or before
205     * setAudioSource()/setVideoSource().
206     * @see android.media.MediaRecorder.OutputFormat
207     */
208    public native void setOutputFormat(int output_format)
209            throws IllegalStateException;
210
211    /**
212     * Sets the width and height of the video to be captured.  Must be called
213     * after setVideoSource(). Call this after setOutFormat() but before
214     * prepare().
215     *
216     * @param width the width of the video to be captured
217     * @param height the height of the video to be captured
218     * @throws IllegalStateException if it is called after
219     * prepare() or before setOutputFormat()
220     */
221    public native void setVideoSize(int width, int height)
222            throws IllegalStateException;
223
224    /**
225     * Sets the frame rate of the video to be captured.  Must be called
226     * after setVideoSource(). Call this after setOutFormat() but before
227     * prepare().
228     *
229     * @param rate the number of frames per second of video to capture
230     * @throws IllegalStateException if it is called after
231     * prepare() or before setOutputFormat().
232     *
233     * NOTE: On some devices that have auto-frame rate, this sets the
234     * maximum frame rate, not a constant frame rate. Actual frame rate
235     * will vary according to lighting conditions.
236     */
237    public native void setVideoFrameRate(int rate) throws IllegalStateException;
238
239    /**
240     * Sets the audio encoder to be used for recording. If this method is not
241     * called, the output file will not contain an audio track. Call this after
242     * setOutputFormat() but before prepare().
243     *
244     * @param audio_encoder the audio encoder to use.
245     * @throws IllegalStateException if it is called before
246     * setOutputFormat() or after prepare().
247     * @see android.media.MediaRecorder.AudioEncoder
248     */
249    public native void setAudioEncoder(int audio_encoder)
250            throws IllegalStateException;
251
252    /**
253     * Sets the video encoder to be used for recording. If this method is not
254     * called, the output file will not contain an video track. Call this after
255     * setOutputFormat() and before prepare().
256     *
257     * @param video_encoder the video encoder to use.
258     * @throws IllegalStateException if it is called before
259     * setOutputFormat() or after prepare()
260     * @see android.media.MediaRecorder.VideoEncoder
261     */
262    public native void setVideoEncoder(int video_encoder)
263            throws IllegalStateException;
264
265    /**
266     * Pass in the file descriptor of the file to be written. Call this after
267     * setOutputFormat() but before prepare().
268     *
269     * @param fd an open file descriptor to be written into.
270     * @throws IllegalStateException if it is called before
271     * setOutputFormat() or after prepare()
272     */
273    public void setOutputFile(FileDescriptor fd) throws IllegalStateException
274    {
275        mPath = null;
276        mFd = fd;
277    }
278
279    /**
280     * Sets the path of the output file to be produced. Call this after
281     * setOutputFormat() but before prepare().
282     *
283     * @param path The pathname to use.
284     * @throws IllegalStateException if it is called before
285     * setOutputFormat() or after prepare()
286     */
287    public void setOutputFile(String path) throws IllegalStateException
288    {
289        mFd = null;
290        mPath = path;
291    }
292
293    // native implementation
294    private native void _setOutputFile(FileDescriptor fd, long offset, long length)
295        throws IllegalStateException, IOException;
296    private native void _prepare() throws IllegalStateException, IOException;
297
298    /**
299     * Prepares the recorder to begin capturing and encoding data. This method
300     * must be called after setting up the desired audio and video sources,
301     * encoders, file format, etc., but before start().
302     *
303     * @throws IllegalStateException if it is called after
304     * start() or before setOutputFormat().
305     * @throws IOException if prepare fails otherwise.
306     */
307    public void prepare() throws IllegalStateException, IOException
308    {
309        if (mPath != null) {
310            FileOutputStream f = new FileOutputStream(mPath);
311            _setOutputFile(f.getFD(), 0, 0);
312        } else if (mFd != null) {
313            _setOutputFile(mFd, 0, 0);
314        } else {
315            throw new IOException("No valid output file");
316        }
317        _prepare();
318    }
319
320    /**
321     * Begins capturing and encoding data to the file specified with
322     * setOutputFile(). Call this after prepare().
323     *
324     * @throws IllegalStateException if it is called before
325     * prepare().
326     */
327    public native void start() throws IllegalStateException;
328
329    /**
330     * Stops recording. Call this after start(). Once recording is stopped,
331     * you will have to configure it again as if it has just been constructed.
332     *
333     * @throws IllegalStateException if it is called before start()
334     */
335    public native void stop() throws IllegalStateException;
336
337    /**
338     * Restarts the MediaRecorder to its idle state. After calling
339     * this method, you will have to configure it again as if it had just been
340     * constructed.
341     */
342    public native void reset();
343
344    /**
345     * Returns the maximum absolute amplitude that was sampled since the last
346     * call to this method. Call this only after the setAudioSource().
347     *
348     * @return the maximum absolute amplitude measured since the last call, or
349     * 0 when called for the first time
350     * @throws IllegalStateException if it is called before
351     * the audio source has been set.
352     */
353    public native int getMaxAmplitude() throws IllegalStateException;
354
355
356    /**
357     * Releases resources associated with this MediaRecorder object.
358     * It is good practice to call this method when you're done
359     * using the MediaRecorder.
360     */
361    public native void release();
362
363    private native final void native_setup() throws IllegalStateException;
364
365    private native final void native_finalize();
366
367    @Override
368    protected void finalize() { native_finalize(); }
369}
370