@@ -96,28 +96,13 @@ class Camera
96
96
* Holds all of the camera features/settings and will be used to update the request builder when
97
97
* one changes.
98
98
*/
99
- private CameraFeatures cameraFeatures ;
100
-
101
- private String imageFormatGroup ;
102
-
103
- /**
104
- * Takes an input/output surface and orients the recording correctly. This is needed because
105
- * switching cameras while recording causes the wrong orientation.
106
- */
107
- private VideoRenderer videoRenderer ;
108
-
109
- /**
110
- * Whether or not the camera aligns with the initial way the camera was facing if the camera was
111
- * flipped.
112
- */
113
- private int initialCameraFacing ;
99
+ private final CameraFeatures cameraFeatures ;
114
100
115
101
private final SurfaceTextureEntry flutterTexture ;
116
- private final ResolutionPreset resolutionPreset ;
117
102
private final boolean enableAudio ;
118
103
private final Context applicationContext ;
119
104
private final DartMessenger dartMessenger ;
120
- private CameraProperties cameraProperties ;
105
+ private final CameraProperties cameraProperties ;
121
106
private final CameraFeatureFactory cameraFeatureFactory ;
122
107
private final Activity activity ;
123
108
/** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture. */
@@ -207,7 +192,6 @@ public Camera(
207
192
this .applicationContext = activity .getApplicationContext ();
208
193
this .cameraProperties = cameraProperties ;
209
194
this .cameraFeatureFactory = cameraFeatureFactory ;
210
- this .resolutionPreset = resolutionPreset ;
211
195
this .cameraFeatures =
212
196
CameraFeatures .init (
213
197
cameraFeatureFactory , cameraProperties , activity , dartMessenger , resolutionPreset );
@@ -248,7 +232,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
248
232
if (mediaRecorder != null ) {
249
233
mediaRecorder .release ();
250
234
}
251
- closeRenderer ();
252
235
253
236
final PlatformChannel .DeviceOrientation lockedOrientation =
254
237
cameraFeatures .getSensorOrientation ().getLockedCaptureOrientation ();
@@ -276,7 +259,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
276
259
277
260
@ SuppressLint ("MissingPermission" )
278
261
public void open (String imageFormatGroup ) throws CameraAccessException {
279
- this .imageFormatGroup = imageFormatGroup ;
280
262
final ResolutionFeature resolutionFeature = cameraFeatures .getResolution ();
281
263
282
264
if (!resolutionFeature .checkIsSupported ()) {
@@ -321,16 +303,14 @@ public void onOpened(@NonNull CameraDevice device) {
321
303
cameraDevice = new DefaultCameraDeviceWrapper (device );
322
304
try {
323
305
startPreview ();
324
- if (!recordingVideo ) // only send initialization if we werent already recording and switching cameras
325
306
dartMessenger .sendCameraInitializedEvent (
326
- resolutionFeature .getPreviewSize ().getWidth (),
327
- resolutionFeature .getPreviewSize ().getHeight (),
328
- cameraFeatures .getExposureLock ().getValue (),
329
- cameraFeatures .getAutoFocus ().getValue (),
330
- cameraFeatures .getExposurePoint ().checkIsSupported (),
331
- cameraFeatures .getFocusPoint ().checkIsSupported ());
332
-
333
- } catch (CameraAccessException | InterruptedException e ) {
307
+ resolutionFeature .getPreviewSize ().getWidth (),
308
+ resolutionFeature .getPreviewSize ().getHeight (),
309
+ cameraFeatures .getExposureLock ().getValue (),
310
+ cameraFeatures .getAutoFocus ().getValue (),
311
+ cameraFeatures .getExposurePoint ().checkIsSupported (),
312
+ cameraFeatures .getFocusPoint ().checkIsSupported ());
313
+ } catch (CameraAccessException e ) {
334
314
dartMessenger .sendCameraErrorEvent (e .getMessage ());
335
315
close ();
336
316
}
@@ -340,8 +320,7 @@ public void onOpened(@NonNull CameraDevice device) {
340
320
public void onClosed (@ NonNull CameraDevice camera ) {
341
321
Log .i (TAG , "open | onClosed" );
342
322
343
- // Prevents calls to methods that would otherwise result in IllegalStateException
344
- // exceptions.
323
+ // Prevents calls to methods that would otherwise result in IllegalStateException exceptions.
345
324
cameraDevice = null ;
346
325
closeCaptureSession ();
347
326
dartMessenger .sendCameraClosingEvent ();
@@ -756,7 +735,7 @@ public void startVideoRecording(
756
735
if (imageStreamChannel != null ) {
757
736
setStreamHandler (imageStreamChannel );
758
737
}
759
- initialCameraFacing = cameraProperties . getLensFacing ();
738
+
760
739
recordingVideo = true ;
761
740
try {
762
741
startCapture (true , imageStreamChannel != null );
@@ -768,13 +747,6 @@ public void startVideoRecording(
768
747
}
769
748
}
770
749
771
- private void closeRenderer () {
772
- if (videoRenderer != null ) {
773
- videoRenderer .close ();
774
- videoRenderer = null ;
775
- }
776
- }
777
-
778
750
public void stopVideoRecording (@ NonNull final Result result ) {
779
751
if (!recordingVideo ) {
780
752
result .success (null );
@@ -785,7 +757,6 @@ public void stopVideoRecording(@NonNull final Result result) {
785
757
cameraFeatureFactory .createAutoFocusFeature (cameraProperties , false ));
786
758
recordingVideo = false ;
787
759
try {
788
- closeRenderer ();
789
760
captureSession .abortCaptures ();
790
761
mediaRecorder .stop ();
791
762
} catch (CameraAccessException | IllegalStateException e ) {
@@ -794,7 +765,7 @@ public void stopVideoRecording(@NonNull final Result result) {
794
765
mediaRecorder .reset ();
795
766
try {
796
767
startPreview ();
797
- } catch (CameraAccessException | IllegalStateException | InterruptedException e ) {
768
+ } catch (CameraAccessException | IllegalStateException e ) {
798
769
result .error ("videoRecordingFailed" , e .getMessage (), null );
799
770
return ;
800
771
}
@@ -1078,48 +1049,11 @@ public void resumePreview() {
1078
1049
null , (code , message ) -> dartMessenger .sendCameraErrorEvent (message ));
1079
1050
}
1080
1051
1081
- public void startPreview () throws CameraAccessException , InterruptedException {
1082
- // If recording is already in progress, the camera is being flipped, so send it through the VideoRenderer to keep the correct orientation.
1083
- if (recordingVideo ) {
1084
- startPreviewWithVideoRendererStream ();
1085
- } else {
1086
- startRegularPreview ();
1087
- }
1088
- }
1089
-
1090
- private void startRegularPreview () throws CameraAccessException {
1052
+ public void startPreview () throws CameraAccessException {
1091
1053
if (pictureImageReader == null || pictureImageReader .getSurface () == null ) return ;
1092
1054
Log .i (TAG , "startPreview" );
1093
- createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , pictureImageReader .getSurface ());
1094
- }
1095
-
1096
- private void startPreviewWithVideoRendererStream ()
1097
- throws CameraAccessException , InterruptedException {
1098
- if (videoRenderer == null ) return ;
1099
-
1100
- // get rotation for rendered video
1101
- final PlatformChannel .DeviceOrientation lockedOrientation =
1102
- cameraFeatures .getSensorOrientation ().getLockedCaptureOrientation ();
1103
- DeviceOrientationManager orientationManager =
1104
- cameraFeatures .getSensorOrientation ().getDeviceOrientationManager ();
1105
-
1106
- int rotation = 0 ;
1107
- if (orientationManager != null ) {
1108
- rotation =
1109
- lockedOrientation == null
1110
- ? orientationManager .getVideoOrientation ()
1111
- : orientationManager .getVideoOrientation (lockedOrientation );
1112
- }
1113
-
1114
- if (cameraProperties .getLensFacing () != initialCameraFacing ) {
1115
-
1116
- // If the new camera is facing the opposite way than the initial recording,
1117
- // the rotation should be flipped 180 degrees.
1118
- rotation = (rotation + 180 ) % 360 ;
1119
- }
1120
- videoRenderer .setRotation (rotation );
1121
1055
1122
- createCaptureSession (CameraDevice .TEMPLATE_RECORD , videoRenderer . getInputSurface ());
1056
+ createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , pictureImageReader . getSurface ());
1123
1057
}
1124
1058
1125
1059
public void startPreviewWithImageStream (EventChannel imageStreamChannel )
@@ -1245,7 +1179,17 @@ private void closeCaptureSession() {
1245
1179
public void close () {
1246
1180
Log .i (TAG , "close" );
1247
1181
1248
- stopAndReleaseCamera ();
1182
+ if (cameraDevice != null ) {
1183
+ cameraDevice .close ();
1184
+ cameraDevice = null ;
1185
+
1186
+ // Closing the CameraDevice without closing the CameraCaptureSession is recommended
1187
+ // for quickly closing the camera:
1188
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1189
+ captureSession = null ;
1190
+ } else {
1191
+ closeCaptureSession ();
1192
+ }
1249
1193
1250
1194
if (pictureImageReader != null ) {
1251
1195
pictureImageReader .close ();
@@ -1264,75 +1208,6 @@ public void close() {
1264
1208
stopBackgroundThread ();
1265
1209
}
1266
1210
1267
- private void stopAndReleaseCamera () {
1268
- if (cameraDevice != null ) {
1269
- cameraDevice .close ();
1270
- cameraDevice = null ;
1271
-
1272
- // Closing the CameraDevice without closing the CameraCaptureSession is recommended
1273
- // for quickly closing the camera:
1274
- // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1275
- captureSession = null ;
1276
- } else {
1277
- closeCaptureSession ();
1278
- }
1279
- }
1280
-
1281
- private void prepareVideoRenderer () {
1282
- if (videoRenderer != null ) return ;
1283
- final ResolutionFeature resolutionFeature = cameraFeatures .getResolution ();
1284
-
1285
- // handle videoRenderer errors
1286
- Thread .UncaughtExceptionHandler videoRendererUncaughtExceptionHandler =
1287
- new Thread .UncaughtExceptionHandler () {
1288
- @ Override
1289
- public void uncaughtException (Thread thread , Throwable ex ) {
1290
- dartMessenger .sendCameraErrorEvent (
1291
- "Failed to process frames after camera was flipped." );
1292
- }
1293
- };
1294
-
1295
- videoRenderer =
1296
- new VideoRenderer (
1297
- mediaRecorder .getSurface (),
1298
- resolutionFeature .getCaptureSize ().getWidth (),
1299
- resolutionFeature .getCaptureSize ().getHeight (),
1300
- videoRendererUncaughtExceptionHandler );
1301
- }
1302
-
1303
- public void setDescriptionWhileRecording (
1304
- @ NonNull final Result result , CameraProperties properties ) {
1305
-
1306
- if (!recordingVideo ) {
1307
- result .error ("setDescriptionWhileRecordingFailed" , "Device was not recording" , null );
1308
- return ;
1309
- }
1310
-
1311
- // See VideoRenderer.java requires API 26 to switch camera while recording
1312
- if (android .os .Build .VERSION .SDK_INT < android .os .Build .VERSION_CODES .O ) {
1313
- result .error (
1314
- "setDescriptionWhileRecordingFailed" ,
1315
- "Device does not support switching the camera while recording" ,
1316
- null );
1317
- return ;
1318
- }
1319
-
1320
- stopAndReleaseCamera ();
1321
- prepareVideoRenderer ();
1322
- cameraProperties = properties ;
1323
- cameraFeatures =
1324
- CameraFeatures .init (
1325
- cameraFeatureFactory , cameraProperties , activity , dartMessenger , resolutionPreset );
1326
- cameraFeatures .setAutoFocus (
1327
- cameraFeatureFactory .createAutoFocusFeature (cameraProperties , true ));
1328
- try {
1329
- open (imageFormatGroup );
1330
- } catch (CameraAccessException e ) {
1331
- result .error ("setDescriptionWhileRecordingFailed" , e .getMessage (), null );
1332
- }
1333
- result .success (null );
1334
- }
1335
-
1336
1211
public void dispose () {
1337
1212
Log .i (TAG , "dispose" );
1338
1213
0 commit comments