前提・実現したいこと
camera2+MediaRecorderでボタンを押したときに映像を5秒間録画するアプリが作成したいです。
起きている問題
ボタンを押した時に、アプリが強制終了してしまいます。
終了したときのログを確認して、MediaRecorderが正常に
動作できていないのは分かったのですが、根本的な解決法が分かりませんでした。
エラー解決の方法など教えていただけないでしょか。
//追記
public void onClick(View v) {内のmRecorder.start();でRuntimeInit.javaに飛びアプリが終了していました。
環境
Android studio 4.0
Android 8.1 API27
java
JAVA
1package com.example.camera2; 2 3public class MainActivity extends Activity { 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate( savedInstanceState ); 8 //カメラ権限 9 int permissionCheck = ContextCompat.checkSelfPermission( MainActivity.this, Manifest.permission.CAMERA ); 10 if (permissionCheck != PackageManager.PERMISSION_GRANTED) { 11 // Android 6.0 以上、該当パーミッションが許可されていない場合 12 final int REQUEST_CODE = 1; 13 ActivityCompat.requestPermissions( MainActivity.this, new String[]{ 14 Manifest.permission.CAMERA 15 16 }, REQUEST_CODE ); 17 18 } 19 //音声権限確認 20 int permissionCheck2 = ContextCompat.checkSelfPermission( MainActivity.this, Manifest.permission.RECORD_AUDIO ); 21 if (permissionCheck2 != PackageManager.PERMISSION_GRANTED) { 22 // Android 6.0 以上、該当パーミッションが許可されていない場合 23 final int REQUEST_CODE = 1; 24 ActivityCompat.requestPermissions( MainActivity.this, new String[]{ 25 Manifest.permission.RECORD_AUDIO 26 27 }, REQUEST_CODE ); 28 29 } 30 setContentView( R.layout.activity_main ); 31 32 mTextureView = (TextureView) findViewById( R.id.texture ); 33 mTextureView.setSurfaceTextureListener( new TextureView.SurfaceTextureListener() { 34 @Override 35 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 36 openCamera(); 37 } 38 39 @Override 40 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 41 42 } 43 44 @Override 45 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 46 return true; 47 } 48 49 @Override 50 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 51 52 } 53 } ); 54 55 Button capture = (Button) findViewById( R.id.button_capture ); 56 capture.setOnClickListener( new View.OnClickListener() { 57 boolean mStartRecording = true; 58 59 @Override 60 public void onClick(View v) { 61 62 if (mIsRecording) { 63 stopRecording(); 64 } else { 65 // initialize video camera 66 if (prepareVideoRecorder()) { 67 68 mRecorder.start(); 69 Toast.makeText( getApplicationContext(), "Started recording", Toast.LENGTH_SHORT ).show(); 70 mIsRecording = true; 71 } else { 72 releaseMediaRecorder(); 73 } 74 } 75 } 76 } ); 77 } 78 79 private void stopRecording() { 80 mRecorder.stop(); // stop the recording 81 releaseMediaRecorder(); // release the MediaRecorder object 82 83 // inform the user that recording has stopped 84 Toast.makeText( this, "Recording complete", Toast.LENGTH_SHORT ).show(); 85 mIsRecording = false; 86 } 87 88 @SuppressLint("MissingPermission") 89 private void openCamera() { 90 CameraManager manager = (CameraManager) getSystemService( Context.CAMERA_SERVICE ); 91 String selectedCameraId = ""; 92 try { 93 selectedCameraId = manager.getCameraIdList()[0]; 94 95 } catch (CameraAccessException e) { 96 e.printStackTrace(); 97 } 98 99 try { 100 if (ActivityCompat.checkSelfPermission( this, Manifest.permission.CAMERA ) != PackageManager.PERMISSION_GRANTED) { 101 // TODO: Consider calling 102 // ActivityCompat#requestPermissions 103 // here to request the missing permissions, and then overriding 104 // public void onRequestPermissionsResult(int requestCode, String[] permissions, 105 // int[] grantResults) 106 // to handle the case where the user grants the permission. See the documentation 107 // for ActivityCompat#requestPermissions for more details. 108 return; 109 } 110 manager.openCamera( selectedCameraId, mStateCallback, mBackgroundHandler ); 111 } catch (CameraAccessException e) { 112 e.printStackTrace(); 113 } 114 } 115 116 private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { 117 @Override 118 public void onOpened(CameraDevice cameraDevice) { 119 mCamera = cameraDevice; 120 createCameraPreviewSession(); 121 } 122 123 @Override 124 public void onDisconnected(CameraDevice cameraDevice) { 125 cameraDevice.close(); 126 mCamera = null; 127 } 128 129 @Override 130 public void onError(CameraDevice cameraDevice, int error) { 131 cameraDevice.close(); 132 mCamera = null; 133 } 134 }; 135 //カメラの権限 136 @Override 137 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 138 @NonNull int[] grantResults) { 139 super.onRequestPermissionsResult( requestCode, permissions, grantResults ); 140 final int REQUEST_CODE = 1; 141 if (requestCode == REQUEST_CODE) { 142 for (int i = 0; i < permissions.length; i++) { 143 final String permission = permissions[i]; 144 final int grantResult = grantResults[i]; 145 146 switch (permission) { 147 case Manifest.permission.CAMERA: 148 if (grantResult == PackageManager.PERMISSION_GRANTED) { 149 //許可されました。 150 } 151 break; 152 default: 153 break; 154 } 155 } 156 } 157 super.onRequestPermissionsResult( requestCode, permissions, grantResults ); 158 if (requestCode == REQUEST_CODE) { 159 for (int i = 0; i < permissions.length; i++) { 160 final String permission2 = permissions[i]; 161 final int grantResult = grantResults[i]; 162 163 switch (permission2) { 164 case Manifest.permission.RECORD_AUDIO: 165 if (grantResult == PackageManager.PERMISSION_GRANTED) { 166 //許可されました。 167 } 168 break; 169 default: 170 break; 171 } 172 } 173 } 174 } 175 private void createCameraPreviewSession() { 176 SurfaceTexture texture = mTextureView.getSurfaceTexture(); 177 texture.setDefaultBufferSize( 1920, 1080 ); 178 Surface surface = new Surface( texture ); 179 180 try { 181 mPreviewRequestBuilder = mCamera.createCaptureRequest( CameraDevice.TEMPLATE_PREVIEW ); 182 mPreviewRequestBuilder.addTarget( surface ); 183 mPreviewRequest = mPreviewRequestBuilder.build(); 184 } catch (CameraAccessException e) { 185 e.printStackTrace(); 186 } 187 188 try { 189 mCamera.createCaptureSession( Arrays.asList( surface ), new CameraCaptureSession.StateCallback() { 190 @Override 191 public void onConfigured(CameraCaptureSession session) { 192 // カメラがcloseされている場合 193 if (null == mCamera) { 194 return; 195 } 196 197 mCaptureSession = session; 198 199 try { 200 session.setRepeatingRequest( mPreviewRequest, null, null ); 201 } catch (CameraAccessException e) { 202 e.printStackTrace(); 203 } 204 } 205 206 @Override 207 public void onConfigureFailed(CameraCaptureSession session) { 208 209 } 210 }, null ); 211 } catch (CameraAccessException e) { 212 e.printStackTrace(); 213 } 214 } 215 216 private boolean prepareVideoRecorder() { 217 mRecorder = new MediaRecorder(); 218 219 220 mRecorder.setAudioSource( MediaRecorder.AudioSource.DEFAULT ); 221 mRecorder.setVideoSource( MediaRecorder.VideoSource.DEFAULT ); 222 mRecorder.setOutputFormat( MediaRecorder.OutputFormat.MPEG_4 ); 223 mRecorder.setVideoEncoder( MediaRecorder.VideoEncoder.H264 ); 224 mRecorder.setAudioEncoder( MediaRecorder.AudioEncoder.AAC ); 225 226 mRecorder.setOutputFile( "/data/data/com.example.camera2/files/video.mp4" ); 227 mRecorder.setMaxDuration( 5000 ); // 5 seconds 228 // Step 6: Prepare configured MediaRecorder 229 try { 230 mRecorder.prepare(); 231 } catch (IllegalStateException e) { 232 Toast.makeText( getApplicationContext(), "exception: " + e.getMessage(), Toast.LENGTH_LONG ).show(); 233 releaseMediaRecorder(); 234 return false; 235 } catch (IOException e) { 236 Toast.makeText( getApplicationContext(), "exception: " + e.getMessage(), Toast.LENGTH_LONG ).show(); 237 releaseMediaRecorder(); 238 return false; 239 } 240 return true; 241 } 242 private void releaseMediaRecorder() { 243 if (mRecorder != null) { 244 mRecorder.reset(); // clear recorder configuration 245 mRecorder.release(); // release the recorder object 246 mRecorder = null; 247 } 248 } 249 250}
あなたの回答
tips
プレビュー