Skip to content

Most visited

Recently visited

navigation
MediaRecorder / src / com.example.android.mediarecorder /

MainActivity.java

1
/*
2
 * Copyright (C) 2013 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
package com.example.android.mediarecorder;
18
 
19
import android.annotation.TargetApi;
20
import android.app.Activity;
21
import android.hardware.Camera;
22
import android.media.CamcorderProfile;
23
import android.media.MediaRecorder;
24
import android.os.AsyncTask;
25
import android.os.Build;
26
import android.os.Bundle;
27
import android.util.Log;
28
import android.view.Menu;
29
import android.view.TextureView;
30
import android.view.View;
31
import android.widget.Button;
32
 
33
import com.example.android.common.media.CameraHelper;
34
 
35
import java.io.File;
36
import java.io.IOException;
37
import java.util.List;
38
 
39
/**
40
 *  This activity uses the camera/camcorder as the A/V source for the {@link android.media.MediaRecorder} API.
41
 *  A {@link android.view.TextureView} is used as the camera preview which limits the code to API 14+. This
42
 *  can be easily replaced with a {@link android.view.SurfaceView} to run on older devices.
43
 */
44
public class MainActivity extends Activity {
45
 
46
    private Camera mCamera;
47
    private TextureView mPreview;
48
    private MediaRecorder mMediaRecorder;
49
    private File mOutputFile;
50
 
51
    private boolean isRecording = false;
52
    private static final String TAG = "Recorder";
53
    private Button captureButton;
54
 
55
    @Override
56
    protected void onCreate(Bundle savedInstanceState) {
57
        super.onCreate(savedInstanceState);
58
        setContentView(R.layout.sample_main);
59
 
60
        mPreview = (TextureView) findViewById(R.id.surface_view);
61
        captureButton = (Button) findViewById(R.id.button_capture);
62
    }
63
 
64
    /**
65
     * The capture button controls all user interaction. When recording, the button click
66
     * stops recording, releases {@link android.media.MediaRecorder} and {@link android.hardware.Camera}. When not recording,
67
     * it prepares the {@link android.media.MediaRecorder} and starts recording.
68
     *
69
     * @param view the view generating the event.
70
     */
71
    public void onCaptureClick(View view) {
72
        if (isRecording) {
74
 
75
            // stop recording and release camera
76
            try {
77
                mMediaRecorder.stop();  // stop the recording
78
            } catch (RuntimeException e) {
79
                // RuntimeException is thrown when stop() is called immediately after start().
80
                // In this case the output file is not properly constructed ans should be deleted.
81
                Log.d(TAG, "RuntimeException: stop() is called immediately after start()");
82
                //noinspection ResultOfMethodCallIgnored
83
                mOutputFile.delete();
84
            }
85
            releaseMediaRecorder(); // release the MediaRecorder object
86
            mCamera.lock();         // take camera access back from MediaRecorder
87
 
88
            // inform the user that recording has stopped
89
            setCaptureButtonText("Capture");
90
            isRecording = false;
91
            releaseCamera();
93
 
94
        } else {
95
 
97
 
98
            new MediaPrepareTask().execute(null, null, null);
99
 
101
 
102
        }
103
    }
104
 
105
    private void setCaptureButtonText(String title) {
106
        captureButton.setText(title);
107
    }
108
 
109
    @Override
110
    protected void onPause() {
111
        super.onPause();
112
        // if we are using MediaRecorder, release it first
113
        releaseMediaRecorder();
114
        // release the camera immediately on pause event
115
        releaseCamera();
116
    }
117
 
118
    private void releaseMediaRecorder(){
119
        if (mMediaRecorder != null) {
120
            // clear recorder configuration
121
            mMediaRecorder.reset();
122
            // release the recorder object
123
            mMediaRecorder.release();
124
            mMediaRecorder = null;
125
            // Lock camera for later use i.e taking it back from MediaRecorder.
126
            // MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
127
            mCamera.lock();
128
        }
129
    }
130
 
131
    private void releaseCamera(){
132
        if (mCamera != null){
133
            // release the camera for other applications
134
            mCamera.release();
135
            mCamera = null;
136
        }
137
    }
138
 
139
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
140
    private boolean prepareVideoRecorder(){
141
 
143
        mCamera = CameraHelper.getDefaultCameraInstance();
144
 
145
        // We need to make sure that our preview and recording video size are supported by the
146
        // camera. Query camera to find all the sizes and choose the optimal size given the
147
        // dimensions of our preview surface.
148
        Camera.Parameters parameters = mCamera.getParameters();
149
        List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
150
        List<Camera.Size> mSupportedVideoSizes = parameters.getSupportedVideoSizes();
151
        Camera.Size optimalSize = CameraHelper.getOptimalVideoSize(mSupportedVideoSizes,
152
                mSupportedPreviewSizes, mPreview.getWidth(), mPreview.getHeight());
153
 
154
        // Use the same size for recording profile.
155
        CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
156
        profile.videoFrameWidth = optimalSize.width;
157
        profile.videoFrameHeight = optimalSize.height;
158
 
159
        // likewise for the camera object itself.
160
        parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
161
        mCamera.setParameters(parameters);
162
        try {
163
                // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
164
                // with {@link SurfaceView}
165
                mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
166
        } catch (IOException e) {
167
            Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
168
            return false;
169
        }
171
 
172
 
174
        mMediaRecorder = new MediaRecorder();
175
 
176
        // Step 1: Unlock and set camera to MediaRecorder
177
        mCamera.unlock();
178
        mMediaRecorder.setCamera(mCamera);
179
 
180
        // Step 2: Set sources
181
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT );
182
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
183
 
184
        // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
185
        mMediaRecorder.setProfile(profile);
186
 
187
        // Step 4: Set output file
188
        mOutputFile = CameraHelper.getOutputMediaFile(CameraHelper.MEDIA_TYPE_VIDEO);
189
        if (mOutputFile == null) {
190
            return false;
191
        }
192
        mMediaRecorder.setOutputFile(mOutputFile.getPath());
194
 
195
        // Step 5: Prepare configured MediaRecorder
196
        try {
197
            mMediaRecorder.prepare();
198
        } catch (IllegalStateException e) {
199
            Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
200
            releaseMediaRecorder();
201
            return false;
202
        } catch (IOException e) {
203
            Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
204
            releaseMediaRecorder();
205
            return false;
206
        }
207
        return true;
208
    }
209
 
210
    /**
211
     * Asynchronous task for preparing the {@link android.media.MediaRecorder} since it's a long blocking
212
     * operation.
213
     */
214
    class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {
215
 
216
        @Override
217
        protected Boolean doInBackground(Void... voids) {
218
            // initialize video camera
219
            if (prepareVideoRecorder()) {
220
                // Camera is available and unlocked, MediaRecorder is prepared,
221
                // now you can start recording
222
                mMediaRecorder.start();
223
 
224
                isRecording = true;
225
            } else {
226
                // prepare didn't work, release the camera
227
                releaseMediaRecorder();
228
                return false;
229
            }
230
            return true;
231
        }
232
 
233
        @Override
234
        protected void onPostExecute(Boolean result) {
235
            if (!result) {
236
                MainActivity.this.finish();
237
            }
238
            // inform the user that recording has started
239
            setCaptureButtonText("Stop");
240
 
241
        }
242
    }
243
 
244
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.