@@ -115,28 +115,13 @@ class Camera
115
115
* Holds all of the camera features/settings and will be used to update the request builder when
116
116
* one changes.
117
117
*/
118
- private CameraFeatures cameraFeatures ;
119
-
120
- private String imageFormatGroup ;
121
-
122
- /**
123
- * Takes an input/output surface and orients the recording correctly. This is needed because
124
- * switching cameras while recording causes the wrong orientation.
125
- */
126
- private VideoRenderer videoRenderer ;
127
-
128
- /**
129
- * Whether or not the camera aligns with the initial way the camera was facing if the camera was
130
- * flipped.
131
- */
132
- private int initialCameraFacing ;
118
+ private final CameraFeatures cameraFeatures ;
133
119
134
120
private final SurfaceTextureEntry flutterTexture ;
135
- private final ResolutionPreset resolutionPreset ;
136
121
private final boolean enableAudio ;
137
122
private final Context applicationContext ;
138
123
private final DartMessenger dartMessenger ;
139
- private CameraProperties cameraProperties ;
124
+ private final CameraProperties cameraProperties ;
140
125
private final CameraFeatureFactory cameraFeatureFactory ;
141
126
private final Activity activity ;
142
127
/** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture. */
@@ -226,7 +211,6 @@ public Camera(
226
211
this .applicationContext = activity .getApplicationContext ();
227
212
this .cameraProperties = cameraProperties ;
228
213
this .cameraFeatureFactory = cameraFeatureFactory ;
229
- this .resolutionPreset = resolutionPreset ;
230
214
this .cameraFeatures =
231
215
CameraFeatures .init (
232
216
cameraFeatureFactory , cameraProperties , activity , dartMessenger , resolutionPreset );
@@ -267,7 +251,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
267
251
if (mediaRecorder != null ) {
268
252
mediaRecorder .release ();
269
253
}
270
- closeRenderer ();
271
254
272
255
final PlatformChannel .DeviceOrientation lockedOrientation =
273
256
((SensorOrientationFeature ) cameraFeatures .getSensorOrientation ())
@@ -296,7 +279,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
296
279
297
280
@ SuppressLint ("MissingPermission" )
298
281
public void open (String imageFormatGroup ) throws CameraAccessException {
299
- this .imageFormatGroup = imageFormatGroup ;
300
282
final ResolutionFeature resolutionFeature = cameraFeatures .getResolution ();
301
283
302
284
if (!resolutionFeature .checkIsSupported ()) {
@@ -341,16 +323,14 @@ public void onOpened(@NonNull CameraDevice device) {
341
323
cameraDevice = new DefaultCameraDeviceWrapper (device );
342
324
try {
343
325
startPreview ();
344
- if (!recordingVideo ) // only send initialization if we werent already recording and switching cameras
345
326
dartMessenger .sendCameraInitializedEvent (
346
- resolutionFeature .getPreviewSize ().getWidth (),
347
- resolutionFeature .getPreviewSize ().getHeight (),
348
- cameraFeatures .getExposureLock ().getValue (),
349
- cameraFeatures .getAutoFocus ().getValue (),
350
- cameraFeatures .getExposurePoint ().checkIsSupported (),
351
- cameraFeatures .getFocusPoint ().checkIsSupported ());
352
-
353
- } catch (CameraAccessException | InterruptedException e ) {
327
+ resolutionFeature .getPreviewSize ().getWidth (),
328
+ resolutionFeature .getPreviewSize ().getHeight (),
329
+ cameraFeatures .getExposureLock ().getValue (),
330
+ cameraFeatures .getAutoFocus ().getValue (),
331
+ cameraFeatures .getExposurePoint ().checkIsSupported (),
332
+ cameraFeatures .getFocusPoint ().checkIsSupported ());
333
+ } catch (CameraAccessException e ) {
354
334
dartMessenger .sendCameraErrorEvent (e .getMessage ());
355
335
close ();
356
336
}
@@ -360,8 +340,7 @@ public void onOpened(@NonNull CameraDevice device) {
360
340
public void onClosed (@ NonNull CameraDevice camera ) {
361
341
Log .i (TAG , "open | onClosed" );
362
342
363
- // Prevents calls to methods that would otherwise result in IllegalStateException
364
- // exceptions.
343
+ // Prevents calls to methods that would otherwise result in IllegalStateException exceptions.
365
344
cameraDevice = null ;
366
345
closeCaptureSession ();
367
346
dartMessenger .sendCameraClosingEvent ();
@@ -777,7 +756,7 @@ public void startVideoRecording(
777
756
if (imageStreamChannel != null ) {
778
757
setStreamHandler (imageStreamChannel );
779
758
}
780
- initialCameraFacing = cameraProperties . getLensFacing ();
759
+
781
760
recordingVideo = true ;
782
761
try {
783
762
startCapture (true , imageStreamChannel != null );
@@ -789,13 +768,6 @@ public void startVideoRecording(
789
768
}
790
769
}
791
770
792
- private void closeRenderer () {
793
- if (videoRenderer != null ) {
794
- videoRenderer .close ();
795
- videoRenderer = null ;
796
- }
797
- }
798
-
799
771
public void stopVideoRecording (@ NonNull final Result result ) {
800
772
if (!recordingVideo ) {
801
773
result .success (null );
@@ -806,7 +778,6 @@ public void stopVideoRecording(@NonNull final Result result) {
806
778
cameraFeatureFactory .createAutoFocusFeature (cameraProperties , false ));
807
779
recordingVideo = false ;
808
780
try {
809
- closeRenderer ();
810
781
captureSession .abortCaptures ();
811
782
mediaRecorder .stop ();
812
783
} catch (CameraAccessException | IllegalStateException e ) {
@@ -815,7 +786,7 @@ public void stopVideoRecording(@NonNull final Result result) {
815
786
mediaRecorder .reset ();
816
787
try {
817
788
startPreview ();
818
- } catch (CameraAccessException | IllegalStateException | InterruptedException e ) {
789
+ } catch (CameraAccessException | IllegalStateException e ) {
819
790
result .error ("videoRecordingFailed" , e .getMessage (), null );
820
791
return ;
821
792
}
@@ -1099,49 +1070,11 @@ public void resumePreview() {
1099
1070
null , (code , message ) -> dartMessenger .sendCameraErrorEvent (message ));
1100
1071
}
1101
1072
1102
- public void startPreview () throws CameraAccessException , InterruptedException {
1103
- // If recording is already in progress, the camera is being flipped, so send it through the VideoRenderer to keep the correct orientation.
1104
- if (recordingVideo ) {
1105
- startPreviewWithVideoRendererStream ();
1106
- } else {
1107
- startRegularPreview ();
1108
- }
1109
- }
1110
-
1111
- private void startRegularPreview () throws CameraAccessException {
1073
+ public void startPreview () throws CameraAccessException {
1112
1074
if (pictureImageReader == null || pictureImageReader .getSurface () == null ) return ;
1113
1075
Log .i (TAG , "startPreview" );
1114
- createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , pictureImageReader .getSurface ());
1115
- }
1116
1076
1117
- private void startPreviewWithVideoRendererStream ()
1118
- throws CameraAccessException , InterruptedException {
1119
- if (videoRenderer == null ) return ;
1120
-
1121
- // get rotation for rendered video
1122
- final PlatformChannel .DeviceOrientation lockedOrientation =
1123
- ((SensorOrientationFeature ) cameraFeatures .getSensorOrientation ())
1124
- .getLockedCaptureOrientation ();
1125
- DeviceOrientationManager orientationManager =
1126
- cameraFeatures .getSensorOrientation ().getDeviceOrientationManager ();
1127
-
1128
- int rotation = 0 ;
1129
- if (orientationManager != null ) {
1130
- rotation =
1131
- lockedOrientation == null
1132
- ? orientationManager .getVideoOrientation ()
1133
- : orientationManager .getVideoOrientation (lockedOrientation );
1134
- }
1135
-
1136
- if (cameraProperties .getLensFacing () != initialCameraFacing ) {
1137
-
1138
- // If the new camera is facing the opposite way than the initial recording,
1139
- // the rotation should be flipped 180 degrees.
1140
- rotation = (rotation + 180 ) % 360 ;
1141
- }
1142
- videoRenderer .setRotation (rotation );
1143
-
1144
- createCaptureSession (CameraDevice .TEMPLATE_RECORD , videoRenderer .getInputSurface ());
1077
+ createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , pictureImageReader .getSurface ());
1145
1078
}
1146
1079
1147
1080
public void startPreviewWithImageStream (EventChannel imageStreamChannel )
@@ -1267,7 +1200,17 @@ private void closeCaptureSession() {
1267
1200
public void close () {
1268
1201
Log .i (TAG , "close" );
1269
1202
1270
- stopAndReleaseCamera ();
1203
+ if (cameraDevice != null ) {
1204
+ cameraDevice .close ();
1205
+ cameraDevice = null ;
1206
+
1207
+ // Closing the CameraDevice without closing the CameraCaptureSession is recommended
1208
+ // for quickly closing the camera:
1209
+ // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1210
+ captureSession = null ;
1211
+ } else {
1212
+ closeCaptureSession ();
1213
+ }
1271
1214
1272
1215
if (pictureImageReader != null ) {
1273
1216
pictureImageReader .close ();
@@ -1286,66 +1229,6 @@ public void close() {
1286
1229
stopBackgroundThread ();
1287
1230
}
1288
1231
1289
- private void stopAndReleaseCamera () {
1290
- if (cameraDevice != null ) {
1291
- cameraDevice .close ();
1292
- cameraDevice = null ;
1293
-
1294
- // Closing the CameraDevice without closing the CameraCaptureSession is recommended
1295
- // for quickly closing the camera:
1296
- // https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1297
- captureSession = null ;
1298
- } else {
1299
- closeCaptureSession ();
1300
- }
1301
- }
1302
-
1303
- private void prepareVideoRenderer () {
1304
- if (videoRenderer != null ) return ;
1305
- final ResolutionFeature resolutionFeature = cameraFeatures .getResolution ();
1306
-
1307
- // handle videoRenderer errors
1308
- Thread .UncaughtExceptionHandler videoRendererUncaughtExceptionHandler =
1309
- new Thread .UncaughtExceptionHandler () {
1310
- @ Override
1311
- public void uncaughtException (Thread thread , Throwable ex ) {
1312
- dartMessenger .sendCameraErrorEvent (
1313
- "Failed to process frames after camera was flipped." );
1314
- }
1315
- };
1316
-
1317
- videoRenderer =
1318
- new VideoRenderer (
1319
- mediaRecorder .getSurface (),
1320
- resolutionFeature .getCaptureSize ().getWidth (),
1321
- resolutionFeature .getCaptureSize ().getHeight (),
1322
- videoRendererUncaughtExceptionHandler );
1323
- }
1324
-
1325
- public void setDescriptionWhileRecording (
1326
- @ NonNull final Result result , CameraProperties properties ) {
1327
-
1328
- if (!recordingVideo ) {
1329
- result .error ("setDescriptionWhileRecordingFailed" , "Device was not recording" , null );
1330
- return ;
1331
- }
1332
-
1333
- stopAndReleaseCamera ();
1334
- prepareVideoRenderer ();
1335
- cameraProperties = properties ;
1336
- cameraFeatures =
1337
- CameraFeatures .init (
1338
- cameraFeatureFactory , cameraProperties , activity , dartMessenger , resolutionPreset );
1339
- cameraFeatures .setAutoFocus (
1340
- cameraFeatureFactory .createAutoFocusFeature (cameraProperties , true ));
1341
- try {
1342
- open (imageFormatGroup );
1343
- } catch (CameraAccessException e ) {
1344
- result .error ("setDescriptionWhileRecordingFailed" , e .getMessage (), null );
1345
- }
1346
- result .success (null );
1347
- }
1348
-
1349
1232
public void dispose () {
1350
1233
Log .i (TAG , "dispose" );
1351
1234
0 commit comments