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.IOException;
36
import java.util.List;
37
 
38
/**
39
 *  This activity uses the camera/camcorder as the A/V source for the {@link android.media.MediaRecorder} API.
40
 *  A {@link android.view.TextureView} is used as the camera preview which limits the code to API 14+. This
41
 *  can be easily replaced with a {@link android.view.SurfaceView} to run on older devices.
42
 */
43
public class MainActivity extends Activity {
44
 
45
    private Camera mCamera;
46
    private TextureView mPreview;
47
    private MediaRecorder mMediaRecorder;
48
 
49
    private boolean isRecording = false;
50
    private static final String TAG = "Recorder";
51
    private Button captureButton;
52
 
53
    @Override
54
    protected void onCreate(Bundle savedInstanceState) {
55
        super.onCreate(savedInstanceState);
56
        setContentView(R.layout.sample_main);
57
 
58
        mPreview = (TextureView) findViewById(R.id.surface_view);
59
        captureButton = (Button) findViewById(R.id.button_capture);
60
    }
61
 
62
    /**
63
     * The capture button controls all user interaction. When recording, the button click
64
     * stops recording, releases {@link android.media.MediaRecorder} and {@link android.hardware.Camera}. When not recording,
65
     * it prepares the {@link android.media.MediaRecorder} and starts recording.
66
     *
67
     * @param view the view generating the event.
68
     */
69
    public void onCaptureClick(View view) {
70
        if (isRecording) {
72
 
73
            // stop recording and release camera
74
            mMediaRecorder.stop();  // stop the recording
75
            releaseMediaRecorder(); // release the MediaRecorder object
76
            mCamera.lock();         // take camera access back from MediaRecorder
77
 
78
            // inform the user that recording has stopped
79
            setCaptureButtonText("Capture");
80
            isRecording = false;
81
            releaseCamera();
83
 
84
        } else {
85
 
87
 
88
            new MediaPrepareTask().execute(null, null, null);
89
 
91
 
92
        }
93
    }
94
 
95
    private void setCaptureButtonText(String title) {
96
        captureButton.setText(title);
97
    }
98
 
99
    @Override
100
    protected void onPause() {
101
        super.onPause();
102
        // if we are using MediaRecorder, release it first
103
        releaseMediaRecorder();
104
        // release the camera immediately on pause event
105
        releaseCamera();
106
    }
107
 
108
    private void releaseMediaRecorder(){
109
        if (mMediaRecorder != null) {
110
            // clear recorder configuration
111
            mMediaRecorder.reset();
112
            // release the recorder object
113
            mMediaRecorder.release();
114
            mMediaRecorder = null;
115
            // Lock camera for later use i.e taking it back from MediaRecorder.
116
            // MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
117
            mCamera.lock();
118
        }
119
    }
120
 
121
    private void releaseCamera(){
122
        if (mCamera != null){
123
            // release the camera for other applications
124
            mCamera.release();
125
            mCamera = null;
126
        }
127
    }
128
 
129
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
130
    private boolean prepareVideoRecorder(){
131
 
133
        mCamera = CameraHelper.getDefaultCameraInstance();
134
 
135
        // We need to make sure that our preview and recording video size are supported by the
136
        // camera. Query camera to find all the sizes and choose the optimal size given the
137
        // dimensions of our preview surface.
138
        Camera.Parameters parameters = mCamera.getParameters();
139
        List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
140
        Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes,
141
                mPreview.getWidth(), mPreview.getHeight());
142
 
143
        // Use the same size for recording profile.
144
        CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
145
        profile.videoFrameWidth = optimalSize.width;
146
        profile.videoFrameHeight = optimalSize.height;
147
 
148
        // likewise for the camera object itself.
149
        parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
150
        mCamera.setParameters(parameters);
151
        try {
152
                // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
153
                // with {@link SurfaceView}
154
                mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
155
        } catch (IOException e) {
156
            Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
157
            return false;
158
        }
160
 
161
 
163
        mMediaRecorder = new MediaRecorder();
164
 
165
        // Step 1: Unlock and set camera to MediaRecorder
166
        mCamera.unlock();
167
        mMediaRecorder.setCamera(mCamera);
168
 
169
        // Step 2: Set sources
170
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT );
171
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
172
 
173
        // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
174
        mMediaRecorder.setProfile(profile);
175
 
176
        // Step 4: Set output file
177
        mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
178
                CameraHelper.MEDIA_TYPE_VIDEO).toString());
180
 
181
        // Step 5: Prepare configured MediaRecorder
182
        try {
183
            mMediaRecorder.prepare();
184
        } catch (IllegalStateException e) {
185
            Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
186
            releaseMediaRecorder();
187
            return false;
188
        } catch (IOException e) {
189
            Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
190
            releaseMediaRecorder();
191
            return false;
192
        }
193
        return true;
194
    }
195
 
196
    /**
197
     * Asynchronous task for preparing the {@link android.media.MediaRecorder} since it's a long blocking
198
     * operation.
199
     */
200
    class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {
201
 
202
        @Override
203
        protected Boolean doInBackground(Void... voids) {
204
            // initialize video camera
205
            if (prepareVideoRecorder()) {
206
                // Camera is available and unlocked, MediaRecorder is prepared,
207
                // now you can start recording
208
                mMediaRecorder.start();
209
 
210
                isRecording = true;
211
            } else {
212
                // prepare didn't work, release the camera
213
                releaseMediaRecorder();
214
                return false;
215
            }
216
            return true;
217
        }
218
 
219
        @Override
220
        protected void onPostExecute(Boolean result) {
221
            if (!result) {
222
                MainActivity.this.finish();
223
            }
224
            // inform the user that recording has started
225
            setCaptureButtonText("Stop");
226
 
227
        }
228
    }
229
 
230
}