@@ -115,28 +115,13 @@ class Camera
115115 * Holds all of the camera features/settings and will be used to update the request builder when
116116 * one changes.
117117 */
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 ;
133119
134120 private final SurfaceTextureEntry flutterTexture ;
135- private final ResolutionPreset resolutionPreset ;
136121 private final boolean enableAudio ;
137122 private final Context applicationContext ;
138123 private final DartMessenger dartMessenger ;
139- private CameraProperties cameraProperties ;
124+ private final CameraProperties cameraProperties ;
140125 private final CameraFeatureFactory cameraFeatureFactory ;
141126 private final Activity activity ;
142127 /** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture. */
@@ -226,7 +211,6 @@ public Camera(
226211 this .applicationContext = activity .getApplicationContext ();
227212 this .cameraProperties = cameraProperties ;
228213 this .cameraFeatureFactory = cameraFeatureFactory ;
229- this .resolutionPreset = resolutionPreset ;
230214 this .cameraFeatures =
231215 CameraFeatures .init (
232216 cameraFeatureFactory , cameraProperties , activity , dartMessenger , resolutionPreset );
@@ -267,7 +251,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
267251 if (mediaRecorder != null ) {
268252 mediaRecorder .release ();
269253 }
270- closeRenderer ();
271254
272255 final PlatformChannel .DeviceOrientation lockedOrientation =
273256 ((SensorOrientationFeature ) cameraFeatures .getSensorOrientation ())
@@ -296,7 +279,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException {
296279
297280 @ SuppressLint ("MissingPermission" )
298281 public void open (String imageFormatGroup ) throws CameraAccessException {
299- this .imageFormatGroup = imageFormatGroup ;
300282 final ResolutionFeature resolutionFeature = cameraFeatures .getResolution ();
301283
302284 if (!resolutionFeature .checkIsSupported ()) {
@@ -341,16 +323,14 @@ public void onOpened(@NonNull CameraDevice device) {
341323 cameraDevice = new DefaultCameraDeviceWrapper (device );
342324 try {
343325 startPreview ();
344- if (!recordingVideo ) // only send initialization if we werent already recording and switching cameras
345326 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 ) {
354334 dartMessenger .sendCameraErrorEvent (e .getMessage ());
355335 close ();
356336 }
@@ -360,8 +340,7 @@ public void onOpened(@NonNull CameraDevice device) {
360340 public void onClosed (@ NonNull CameraDevice camera ) {
361341 Log .i (TAG , "open | onClosed" );
362342
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.
365344 cameraDevice = null ;
366345 closeCaptureSession ();
367346 dartMessenger .sendCameraClosingEvent ();
@@ -777,7 +756,7 @@ public void startVideoRecording(
777756 if (imageStreamChannel != null ) {
778757 setStreamHandler (imageStreamChannel );
779758 }
780- initialCameraFacing = cameraProperties . getLensFacing ();
759+
781760 recordingVideo = true ;
782761 try {
783762 startCapture (true , imageStreamChannel != null );
@@ -789,13 +768,6 @@ public void startVideoRecording(
789768 }
790769 }
791770
792- private void closeRenderer () {
793- if (videoRenderer != null ) {
794- videoRenderer .close ();
795- videoRenderer = null ;
796- }
797- }
798-
799771 public void stopVideoRecording (@ NonNull final Result result ) {
800772 if (!recordingVideo ) {
801773 result .success (null );
@@ -806,7 +778,6 @@ public void stopVideoRecording(@NonNull final Result result) {
806778 cameraFeatureFactory .createAutoFocusFeature (cameraProperties , false ));
807779 recordingVideo = false ;
808780 try {
809- closeRenderer ();
810781 captureSession .abortCaptures ();
811782 mediaRecorder .stop ();
812783 } catch (CameraAccessException | IllegalStateException e ) {
@@ -815,7 +786,7 @@ public void stopVideoRecording(@NonNull final Result result) {
815786 mediaRecorder .reset ();
816787 try {
817788 startPreview ();
818- } catch (CameraAccessException | IllegalStateException | InterruptedException e ) {
789+ } catch (CameraAccessException | IllegalStateException e ) {
819790 result .error ("videoRecordingFailed" , e .getMessage (), null );
820791 return ;
821792 }
@@ -1099,49 +1070,11 @@ public void resumePreview() {
10991070 null , (code , message ) -> dartMessenger .sendCameraErrorEvent (message ));
11001071 }
11011072
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 {
11121074 if (pictureImageReader == null || pictureImageReader .getSurface () == null ) return ;
11131075 Log .i (TAG , "startPreview" );
1114- createCaptureSession (CameraDevice .TEMPLATE_PREVIEW , pictureImageReader .getSurface ());
1115- }
11161076
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 ());
11451078 }
11461079
11471080 public void startPreviewWithImageStream (EventChannel imageStreamChannel )
@@ -1267,7 +1200,17 @@ private void closeCaptureSession() {
12671200 public void close () {
12681201 Log .i (TAG , "close" );
12691202
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+ }
12711214
12721215 if (pictureImageReader != null ) {
12731216 pictureImageReader .close ();
@@ -1286,66 +1229,6 @@ public void close() {
12861229 stopBackgroundThread ();
12871230 }
12881231
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-
13491232 public void dispose () {
13501233 Log .i (TAG , "dispose" );
13511234
0 commit comments