diff options
author | Rastislav Kostrab <r.kostrab@gmail.com> | 2016-01-19 18:30:53 +0900 |
---|---|---|
committer | Yuichi Araki <yaraki@google.com> | 2016-01-21 17:17:37 +0900 |
commit | 0696dbf386d0e9f2f91ab911520a45f3abd65b96 (patch) | |
tree | 78006c2c295b51a66b44e0f41b51440420722475 /media | |
parent | 90ec985bba5710f733d8959530163a480d1e84d4 (diff) | |
download | android-0696dbf386d0e9f2f91ab911520a45f3abd65b96.tar.gz |
Camera2Video: Several fixes
https://github.com/googlesamples/android-Camera2Video/pull/19
bugfixes: recognition of camera sensor orientation, closing preview
session properly, setting MediaRecorder and recording after pressing the
button
Change-Id: I6e7ec3fb1dc2069d39e049dced4b3c3781013d87
Diffstat (limited to 'media')
3 files changed, 100 insertions, 36 deletions
diff --git a/media/Camera2Video/Application/src/main/AndroidManifest.xml b/media/Camera2Video/Application/src/main/AndroidManifest.xml index 5cb54286..67a90d06 100644 --- a/media/Camera2Video/Application/src/main/AndroidManifest.xml +++ b/media/Camera2Video/Application/src/main/AndroidManifest.xml @@ -23,6 +23,7 @@ <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:label="@string/app_name" diff --git a/media/Camera2Video/Application/src/main/java/com/example/android/camera2video/Camera2VideoFragment.java b/media/Camera2Video/Application/src/main/java/com/example/android/camera2video/Camera2VideoFragment.java index 1ea53187..0d96ba2c 100644 --- a/media/Camera2Video/Application/src/main/java/com/example/android/camera2video/Camera2VideoFragment.java +++ b/media/Camera2Video/Application/src/main/java/com/example/android/camera2video/Camera2VideoFragment.java @@ -55,9 +55,9 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; -import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -67,7 +67,10 @@ import java.util.concurrent.TimeUnit; public class Camera2VideoFragment extends Fragment implements View.OnClickListener, FragmentCompat.OnRequestPermissionsResultCallback { - private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); + private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90; + private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270; + private static final SparseIntArray DEFAULT_ORIENTATIONS = new SparseIntArray(); + private static final SparseIntArray INVERSE_ORIENTATIONS = new SparseIntArray(); private static final String TAG = "Camera2VideoFragment"; private static final int REQUEST_VIDEO_PERMISSIONS = 1; @@ -79,10 +82,17 @@ public class Camera2VideoFragment extends Fragment }; static { - ORIENTATIONS.append(Surface.ROTATION_0, 90); - ORIENTATIONS.append(Surface.ROTATION_90, 0); - ORIENTATIONS.append(Surface.ROTATION_180, 270); - ORIENTATIONS.append(Surface.ROTATION_270, 180); + DEFAULT_ORIENTATIONS.append(Surface.ROTATION_0, 90); + DEFAULT_ORIENTATIONS.append(Surface.ROTATION_90, 0); + DEFAULT_ORIENTATIONS.append(Surface.ROTATION_180, 270); + DEFAULT_ORIENTATIONS.append(Surface.ROTATION_270, 180); + } + + static { + INVERSE_ORIENTATIONS.append(Surface.ROTATION_0, 270); + INVERSE_ORIENTATIONS.append(Surface.ROTATION_90, 180); + INVERSE_ORIENTATIONS.append(Surface.ROTATION_180, 90); + INVERSE_ORIENTATIONS.append(Surface.ROTATION_270, 0); } /** @@ -147,11 +157,6 @@ public class Camera2VideoFragment extends Fragment private Size mVideoSize; /** - * Camera preview. - */ - private CaptureRequest.Builder mPreviewBuilder; - - /** * MediaRecorder */ private MediaRecorder mMediaRecorder; @@ -210,6 +215,10 @@ public class Camera2VideoFragment extends Fragment } }; + private Integer mSensorOrientation; + private String mNextVideoAbsolutePath; + private CaptureRequest.Builder mPreviewBuilder; + private Surface mRecorderSurface; public static Camera2VideoFragment newInstance() { return new Camera2VideoFragment(); @@ -425,6 +434,7 @@ public class Camera2VideoFragment extends Fragment CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); + mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class)); mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height, mVideoSize); @@ -454,6 +464,7 @@ public class Camera2VideoFragment extends Fragment private void closeCamera() { try { mCameraOpenCloseLock.acquire(); + closePreviewSession(); if (null != mCameraDevice) { mCameraDevice.close(); mCameraDevice = null; @@ -477,22 +488,16 @@ public class Camera2VideoFragment extends Fragment return; } try { - setUpMediaRecorder(); + closePreviewSession(); SurfaceTexture texture = mTextureView.getSurfaceTexture(); assert texture != null; texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); - mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); - List<Surface> surfaces = new ArrayList<Surface>(); + mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); Surface previewSurface = new Surface(texture); - surfaces.add(previewSurface); mPreviewBuilder.addTarget(previewSurface); - Surface recorderSurface = mMediaRecorder.getSurface(); - surfaces.add(recorderSurface); - mPreviewBuilder.addTarget(recorderSurface); - - mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { + mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { @@ -510,8 +515,6 @@ public class Camera2VideoFragment extends Fragment }, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); } } @@ -575,33 +578,91 @@ public class Camera2VideoFragment extends Fragment mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath()); + if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) { + mNextVideoAbsolutePath = getVideoFilePath(getActivity()); + } + mMediaRecorder.setOutputFile(mNextVideoAbsolutePath); mMediaRecorder.setVideoEncodingBitRate(10000000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); - int orientation = ORIENTATIONS.get(rotation); - mMediaRecorder.setOrientationHint(orientation); + switch (mSensorOrientation) { + case SENSOR_ORIENTATION_DEFAULT_DEGREES: + mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation)); + break; + case SENSOR_ORIENTATION_INVERSE_DEGREES: + mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation)); + break; + } mMediaRecorder.prepare(); } - private File getVideoFile(Context context) { - return new File(context.getExternalFilesDir(null), "video.mp4"); + private String getVideoFilePath(Context context) { + return context.getExternalFilesDir(null).getAbsolutePath() + "/" + System.currentTimeMillis() + ".mp4"; } private void startRecordingVideo() { + if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { + return; + } try { - // UI - mButtonVideo.setText(R.string.stop); - mIsRecordingVideo = true; + closePreviewSession(); + setUpMediaRecorder(); + SurfaceTexture texture = mTextureView.getSurfaceTexture(); + assert texture != null; + texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); + mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); + List<Surface> surfaces = new ArrayList<Surface>(); + + Surface previewSurface = new Surface(texture); + surfaces.add(previewSurface); + mPreviewBuilder.addTarget(previewSurface); + + mRecorderSurface = mMediaRecorder.getSurface(); + surfaces.add(mRecorderSurface); + mPreviewBuilder.addTarget(mRecorderSurface); + mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { - // Start recording - mMediaRecorder.start(); - } catch (IllegalStateException e) { + @Override + public void onConfigured(CameraCaptureSession cameraCaptureSession) { + mPreviewSession = cameraCaptureSession; + updatePreview(); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + // UI + mButtonVideo.setText(R.string.stop); + mIsRecordingVideo = true; + + // Start recording + mMediaRecorder.start(); + } + }); + } + + @Override + public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { + Activity activity = getActivity(); + if (null != activity) { + Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show(); + } + } + }, mBackgroundHandler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } catch (IOException e) { e.printStackTrace(); } + + } + + private void closePreviewSession() { + if(mPreviewSession != null) { + mPreviewSession.close(); + mPreviewSession = null; + } } private void stopRecordingVideo() { @@ -611,11 +672,13 @@ public class Camera2VideoFragment extends Fragment // Stop recording mMediaRecorder.stop(); mMediaRecorder.reset(); + Activity activity = getActivity(); if (null != activity) { - Toast.makeText(activity, "Video saved: " + getVideoFile(activity), + Toast.makeText(activity, "Video saved: " + mNextVideoAbsolutePath, Toast.LENGTH_SHORT).show(); } + mNextVideoAbsolutePath = null; startPreview(); } @@ -687,4 +750,4 @@ public class Camera2VideoFragment extends Fragment } -} +}
\ No newline at end of file diff --git a/media/Camera2Video/README.md b/media/Camera2Video/README.md index ac5084ca..e1f07bc9 100644 --- a/media/Camera2Video/README.md +++ b/media/Camera2Video/README.md @@ -44,7 +44,7 @@ Pre-requisites -------------- - Android SDK v23 -- Android Build Tools v23.0.0 +- Android Build Tools v23.0.2 - Android Support Repository Screenshots |