diff options
Diffstat (limited to 'media/java/android/media/MediaRecorder.java')
-rw-r--r-- | media/java/android/media/MediaRecorder.java | 238 |
1 files changed, 58 insertions, 180 deletions
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 4906cbb..3609826 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -16,27 +16,23 @@ package android.media; -import android.hardware.Camera; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; import android.view.Surface; +import android.hardware.Camera; import java.io.IOException; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileDescriptor; -import java.lang.ref.WeakReference; +import android.util.Log; /** * Used to record audio and video. The recording control is based on a - * simple state machine (see below). - * + * simple state machine (see below). + * * <p><img src="{@docRoot}images/mediarecorder_state_diagram.gif" border="0" /> * </p> - * + * * <p>A common case of using MediaRecorder to record audio works as follows: - * + * * <pre>MediaRecorder recorder = new MediaRecorder(); * recorder.setAudioSource(MediaRecorder.AudioSource.MIC); * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); @@ -49,54 +45,39 @@ import java.lang.ref.WeakReference; * recorder.reset(); // You can reuse the object by going back to setAudioSource() step * recorder.release(); // Now the object cannot be reused * </pre> - * + * * <p>See the <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a> * documentation for additional help with using MediaRecorder. */ public class MediaRecorder -{ +{ static { System.loadLibrary("media_jni"); } private final static String TAG = "MediaRecorder"; - + // The two fields below are accessed by native methods @SuppressWarnings("unused") private int mNativeContext; - + @SuppressWarnings("unused") private Surface mSurface; private String mPath; private FileDescriptor mFd; - private EventHandler mEventHandler; - private OnErrorListener mOnErrorListener; /** * Default constructor. */ public MediaRecorder() { - - Looper looper; - if ((looper = Looper.myLooper()) != null) { - mEventHandler = new EventHandler(this, looper); - } else if ((looper = Looper.getMainLooper()) != null) { - mEventHandler = new EventHandler(this, looper); - } else { - mEventHandler = null; - } - - /* Native setup requires a weak reference to our object. - * It's easier to create it here than in C++. - */ - native_setup(new WeakReference<MediaRecorder>(this)); + native_setup(); } - + /** * Sets a Camera to use for recording. Use this function to switch * quickly between preview and capture mode without a teardown of * the camera object. Must call before prepare(). - * + * * @param c the Camera to use for recording */ public native void setCamera(Camera c); @@ -105,15 +86,15 @@ public class MediaRecorder * Sets a Surface to show a preview of recorded media (video). Calls this * before prepare() to make sure that the desirable preview display is * set. - * + * * @param sv the Surface to use for the preview */ public void setPreviewDisplay(Surface sv) { mSurface = sv; } - + /** - * Defines the audio source. These constants are used with + * Defines the audio source. These constants are used with * {@link MediaRecorder#setAudioSource(int)}. */ public final class AudioSource { @@ -127,7 +108,7 @@ public class MediaRecorder } /** - * Defines the video source. These constants are used with + * Defines the video source. These constants are used with * {@link MediaRecorder#setVideoSource(int)}. */ public final class VideoSource { @@ -141,7 +122,7 @@ public class MediaRecorder } /** - * Defines the output format. These constants are used with + * Defines the output format. These constants are used with * {@link MediaRecorder#setOutputFormat(int)}. */ public final class OutputFormat { @@ -159,7 +140,7 @@ public class MediaRecorder }; /** - * Defines the audio encoding. These constants are used with + * Defines the audio encoding. These constants are used with * {@link MediaRecorder#setAudioEncoder(int)}. */ public final class AudioEncoder { @@ -174,7 +155,7 @@ public class MediaRecorder } /** - * Defines the video encoding. These constants are used with + * Defines the video encoding. These constants are used with * {@link MediaRecorder#setVideoEncoder(int)}. */ public final class VideoEncoder { @@ -191,50 +172,50 @@ public class MediaRecorder /** * Sets the audio source to be used for recording. If this method is not * called, the output file will not contain an audio track. The source needs - * to be specified before setting recording-parameters or encoders. Call + * to be specified before setting recording-parameters or encoders. Call * this only before setOutputFormat(). - * + * * @param audio_source the audio source to use * @throws IllegalStateException if it is called after setOutputFormat() * @see android.media.MediaRecorder.AudioSource - */ + */ public native void setAudioSource(int audio_source) throws IllegalStateException; /** * Sets the video source to be used for recording. If this method is not * called, the output file will not contain an video track. The source needs - * to be specified before setting recording-parameters or encoders. Call + * to be specified before setting recording-parameters or encoders. Call * this only before setOutputFormat(). - * + * * @param video_source the video source to use * @throws IllegalStateException if it is called after setOutputFormat() * @see android.media.MediaRecorder.VideoSource - */ + */ public native void setVideoSource(int video_source) throws IllegalStateException; /** * Sets the format of the output file produced during recording. Call this * after setAudioSource()/setVideoSource() but before prepare(). - * - * @param output_format the output format to use. The output format + * + * @param output_format the output format to use. The output format * needs to be specified before setting recording-parameters or encoders. * @throws IllegalStateException if it is called after prepare() or before * setAudioSource()/setVideoSource(). * @see android.media.MediaRecorder.OutputFormat - */ + */ public native void setOutputFormat(int output_format) throws IllegalStateException; - + /** * Sets the width and height of the video to be captured. Must be called * after setVideoSource(). Call this after setOutFormat() but before * prepare(). - * + * * @param width the width of the video to be captured * @param height the height of the video to be captured - * @throws IllegalStateException if it is called after + * @throws IllegalStateException if it is called after * prepare() or before setOutputFormat() */ public native void setVideoSize(int width, int height) @@ -246,7 +227,7 @@ public class MediaRecorder * prepare(). * * @param rate the number of frames per second of video to capture - * @throws IllegalStateException if it is called after + * @throws IllegalStateException if it is called after * prepare() or before setOutputFormat(). * * NOTE: On some devices that have auto-frame rate, this sets the @@ -259,12 +240,12 @@ public class MediaRecorder * Sets the audio encoder to be used for recording. If this method is not * called, the output file will not contain an audio track. Call this after * setOutputFormat() but before prepare(). - * + * * @param audio_encoder the audio encoder to use. * @throws IllegalStateException if it is called before * setOutputFormat() or after prepare(). * @see android.media.MediaRecorder.AudioEncoder - */ + */ public native void setAudioEncoder(int audio_encoder) throws IllegalStateException; @@ -272,43 +253,43 @@ public class MediaRecorder * Sets the video encoder to be used for recording. If this method is not * called, the output file will not contain an video track. Call this after * setOutputFormat() and before prepare(). - * + * * @param video_encoder the video encoder to use. * @throws IllegalStateException if it is called before * setOutputFormat() or after prepare() * @see android.media.MediaRecorder.VideoEncoder - */ + */ public native void setVideoEncoder(int video_encoder) throws IllegalStateException; /** * Pass in the file descriptor of the file to be written. Call this after * setOutputFormat() but before prepare(). - * + * * @param fd an open file descriptor to be written into. * @throws IllegalStateException if it is called before * setOutputFormat() or after prepare() - */ + */ public void setOutputFile(FileDescriptor fd) throws IllegalStateException { mPath = null; mFd = fd; } - + /** * Sets the path of the output file to be produced. Call this after * setOutputFormat() but before prepare(). - * + * * @param path The pathname to use. * @throws IllegalStateException if it is called before * setOutputFormat() or after prepare() - */ + */ public void setOutputFile(String path) throws IllegalStateException { mFd = null; mPath = path; } - + // native implementation private native void _setOutputFile(FileDescriptor fd, long offset, long length) throws IllegalStateException, IOException; @@ -318,7 +299,7 @@ public class MediaRecorder * Prepares the recorder to begin capturing and encoding data. This method * must be called after setting up the desired audio and video sources, * encoders, file format, etc., but before start(). - * + * * @throws IllegalStateException if it is called after * start() or before setOutputFormat(). * @throws IOException if prepare fails otherwise. @@ -326,12 +307,8 @@ public class MediaRecorder public void prepare() throws IllegalStateException, IOException { if (mPath != null) { - FileOutputStream fos = new FileOutputStream(mPath); - try { - _setOutputFile(fos.getFD(), 0, 0); - } finally { - fos.close(); - } + FileOutputStream f = new FileOutputStream(mPath); + _setOutputFile(f.getFD(), 0, 0); } else if (mFd != null) { _setOutputFile(mFd, 0, 0); } else { @@ -341,9 +318,9 @@ public class MediaRecorder } /** - * Begins capturing and encoding data to the file specified with + * Begins capturing and encoding data to the file specified with * setOutputFile(). Call this after prepare(). - * + * * @throws IllegalStateException if it is called before * prepare(). */ @@ -352,7 +329,7 @@ public class MediaRecorder /** * Stops recording. Call this after start(). Once recording is stopped, * you will have to configure it again as if it has just been constructed. - * + * * @throws IllegalStateException if it is called before start() */ public native void stop() throws IllegalStateException; @@ -362,118 +339,19 @@ public class MediaRecorder * this method, you will have to configure it again as if it had just been * constructed. */ - public void reset() { - native_reset(); - - // make sure none of the listeners get called anymore - mEventHandler.removeCallbacksAndMessages(null); - } - - private native void native_reset(); - + public native void reset(); + /** - * Returns the maximum absolute amplitude that was sampled since the last + * Returns the maximum absolute amplitude that was sampled since the last * call to this method. Call this only after the setAudioSource(). - * - * @return the maximum absolute amplitude measured since the last call, or + * + * @return the maximum absolute amplitude measured since the last call, or * 0 when called for the first time * @throws IllegalStateException if it is called before * the audio source has been set. */ public native int getMaxAmplitude() throws IllegalStateException; - - /* Do not change this value without updating its counterpart - * in include/media/mediarecorder.h! - */ - /** Unspecified media recorder error. - * @see android.media.MediaRecorder.OnErrorListener - */ - public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1; - - /** - * Interface definition for a callback to be invoked when an error - * occurs while recording. - */ - public interface OnErrorListener - { - /** - * Called when an error occurs while recording. - * - * @param mr the MediaRecorder that encountered the error - * @param what the type of error that has occurred: - * <ul> - * <li>{@link #MEDIA_RECORDER_ERROR_UNKNOWN} - * </ul> - * @param extra an extra code, specific to the error type - */ - void onError(MediaRecorder mr, int what, int extra); - } - - /** - * Register a callback to be invoked when an error occurs while - * recording. - * - * @param l the callback that will be run - */ - public void setOnErrorListener(OnErrorListener l) - { - mOnErrorListener = l; - } - - private class EventHandler extends Handler - { - private MediaRecorder mMediaRecorder; - - public EventHandler(MediaRecorder mr, Looper looper) { - super(looper); - mMediaRecorder = mr; - } - - /* Do not change this value without updating its counterpart - * in include/media/mediarecorder.h! - */ - private static final int MEDIA_RECORDER_EVENT_ERROR = 1; - - @Override - public void handleMessage(Message msg) { - if (mMediaRecorder.mNativeContext == 0) { - Log.w(TAG, "mediarecorder went away with unhandled events"); - return; - } - switch(msg.what) { - case MEDIA_RECORDER_EVENT_ERROR: - if (mOnErrorListener != null) - mOnErrorListener.onError(mMediaRecorder, msg.arg1, msg.arg2); - - return; - - default: - Log.e(TAG, "Unknown message type " + msg.what); - return; - } - } - } - - /** - * Called from native code when an interesting event happens. This method - * just uses the EventHandler system to post the event back to the main app thread. - * We use a weak reference to the original MediaRecorder object so that the native - * code is safe from the object disappearing from underneath it. (This is - * the cookie passed to native_setup().) - */ - private static void postEventFromNative(Object mediarecorder_ref, - int what, int arg1, int arg2, Object obj) - { - MediaRecorder mr = (MediaRecorder)((WeakReference)mediarecorder_ref).get(); - if (mr == null) { - return; - } - - if (mr.mEventHandler != null) { - Message m = mr.mEventHandler.obtainMessage(what, arg1, arg2, obj); - mr.mEventHandler.sendMessage(m); - } - } + /** * Releases resources associated with this MediaRecorder object. @@ -482,10 +360,10 @@ public class MediaRecorder */ public native void release(); - private native final void native_setup(Object mediarecorder_this) throws IllegalStateException; - + private native final void native_setup() throws IllegalStateException; + private native final void native_finalize(); - + @Override protected void finalize() { native_finalize(); } } |