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.