@@ -4,8 +4,6 @@ import android.annotation.SuppressLint
4
4
import android.app.AlertDialog
5
5
import android.content.Context
6
6
import android.content.SharedPreferences
7
- import android.hardware.camera2.CameraMetadata
8
- import android.hardware.camera2.CaptureRequest
9
7
import android.net.Uri
10
8
import android.os.Build
11
9
import android.provider.MediaStore
@@ -18,12 +16,13 @@ import android.view.animation.Animation
18
16
import android.view.animation.LinearInterpolator
19
17
import android.widget.Button
20
18
import androidx.annotation.StringRes
21
- import androidx.camera.camera2.interop.Camera2Interop
22
19
import androidx.camera.core.AspectRatio
23
20
import androidx.camera.core.Camera
21
+ import androidx.camera.core.CameraInfo
24
22
import androidx.camera.core.CameraSelector
25
23
import androidx.camera.core.ImageAnalysis
26
24
import androidx.camera.core.ImageCapture
25
+ import androidx.camera.core.MirrorMode
27
26
import androidx.camera.core.Preview
28
27
import androidx.camera.core.TorchState
29
28
import androidx.camera.core.UseCaseGroup
@@ -91,6 +90,7 @@ class CamConfig(private val mActivity: MainActivity) {
91
90
const val SCAN = " scan"
92
91
const val SCAN_ALL_CODES = " scan_all_codes"
93
92
const val SAVE_IMAGE_AS_PREVIEW = " save_image_as_preview"
93
+ const val SAVE_VIDEO_AS_PREVIEW = " save_video_as_preview"
94
94
95
95
const val STORAGE_LOCATION = " storage_location"
96
96
const val PREVIOUS_SAF_TREES = " previous_saf_trees"
@@ -140,6 +140,8 @@ class CamConfig(private val mActivity: MainActivity) {
140
140
141
141
const val SAVE_IMAGE_AS_PREVIEW = false
142
142
143
+ const val SAVE_VIDEO_AS_PREVIEW = false
144
+
143
145
const val STORAGE_LOCATION = " "
144
146
145
147
const val PHOTO_QUALITY = 0
@@ -218,6 +220,10 @@ class CamConfig(private val mActivity: MainActivity) {
218
220
219
221
var lastCapturedItem: CapturedItem ? = null
220
222
223
+ private var frontCameraInfo : CameraInfo ? = null
224
+
225
+ private var rearCameraInfo : CameraInfo ? = null
226
+
221
227
init {
222
228
if (mActivity !is SecureActivity ) {
223
229
CapturedItems .init (mActivity, this )
@@ -429,7 +435,7 @@ class CamConfig(private val mActivity: MainActivity) {
429
435
430
436
var enableEIS: Boolean
431
437
get() {
432
- return mActivity.settingsDialog.enableEISToggle.isChecked
438
+ return isStabilizationSupported() && mActivity.settingsDialog.enableEISToggle.isChecked
433
439
}
434
440
set(value) {
435
441
val editor = commonPref.edit()
@@ -465,6 +471,19 @@ class CamConfig(private val mActivity: MainActivity) {
465
471
editor.apply ()
466
472
}
467
473
474
+ var saveVideoAsPreviewed: Boolean
475
+ get() {
476
+ return commonPref.getBoolean(
477
+ SettingValues .Key .SAVE_VIDEO_AS_PREVIEW ,
478
+ SettingValues .Default .SAVE_VIDEO_AS_PREVIEW
479
+ )
480
+ }
481
+ set(value) {
482
+ val editor = commonPref.edit()
483
+ editor.putBoolean(SettingValues .Key .SAVE_VIDEO_AS_PREVIEW , value)
484
+ editor.apply ()
485
+ }
486
+
468
487
var storageLocation: String
469
488
get() {
470
489
return commonPref.getString(
@@ -532,6 +551,10 @@ class CamConfig(private val mActivity: MainActivity) {
532
551
camera!! .cameraInfo.isZslSupported
533
552
}
534
553
554
+ fun isStabilizationSupported () : Boolean {
555
+ return Recorder .getVideoCapabilities(getCurrentCameraInfo()).isStabilizationSupported
556
+ }
557
+
535
558
fun shouldShowGyroscope (): Boolean {
536
559
return isInPhotoMode && gSuggestions
537
560
}
@@ -894,6 +917,11 @@ class CamConfig(private val mActivity: MainActivity) {
894
917
startCamera(true )
895
918
}
896
919
920
+ private fun getCurrentCameraInfo () : CameraInfo {
921
+ return if (lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo!!
922
+ else frontCameraInfo!!
923
+ }
924
+
897
925
fun toggleCameraSelector () {
898
926
899
927
// Manually switch to the opposite lens facing
@@ -937,6 +965,12 @@ class CamConfig(private val mActivity: MainActivity) {
937
965
return
938
966
}
939
967
968
+ // Select a single camera for front/rear facing
969
+ for (cameraInfo in cameraProvider!! .availableCameraInfos) {
970
+ if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_FRONT ) frontCameraInfo = cameraInfo
971
+ else if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo = cameraInfo
972
+ }
973
+
940
974
// Manually switch to the other lens facing (if the default lens facing isn't
941
975
// supported for the current device)
942
976
if (! isLensFacingSupported(lensFacing)) {
@@ -963,11 +997,11 @@ class CamConfig(private val mActivity: MainActivity) {
963
997
}
964
998
965
999
private fun isLensFacingSupported (lensFacing : Int ) : Boolean {
966
- val tCameraSelector = CameraSelector . Builder ()
967
- .requireLensFacing(lensFacing)
968
- .build()
969
-
970
- return cameraProvider?.hasCamera(tCameraSelector) ? : false
1000
+ return when (lensFacing) {
1001
+ CameraSelector . LENS_FACING_FRONT -> frontCameraInfo != null
1002
+ CameraSelector . LENS_FACING_BACK -> rearCameraInfo != null
1003
+ else -> false
1004
+ }
971
1005
}
972
1006
973
1007
// Start the camera with latest hard configuration
@@ -993,6 +1027,15 @@ class CamConfig(private val mActivity: MainActivity) {
993
1027
994
1028
cameraSelector = CameraSelector .Builder ()
995
1029
.requireLensFacing(lensFacing)
1030
+ .addCameraFilter {
1031
+ return @addCameraFilter listOf (
1032
+ if (lensFacing == CameraSelector .LENS_FACING_BACK ) {
1033
+ rearCameraInfo
1034
+ } else {
1035
+ frontCameraInfo
1036
+ }
1037
+ )
1038
+ }
996
1039
.build()
997
1040
998
1041
val builder = ImageCapture .Builder ()
@@ -1053,12 +1096,18 @@ class CamConfig(private val mActivity: MainActivity) {
1053
1096
View .VISIBLE
1054
1097
}
1055
1098
1056
- videoCapture =
1057
- VideoCapture .withOutput(
1058
- Recorder .Builder ()
1059
- .setQualitySelector(QualitySelector .from(videoQuality))
1060
- .build()
1061
- )
1099
+ val videoCaptureBuilder = VideoCapture .Builder (
1100
+ Recorder .Builder ()
1101
+ .setQualitySelector(QualitySelector .from(videoQuality))
1102
+ .build()
1103
+ )
1104
+
1105
+ videoCaptureBuilder.setVideoStabilizationEnabled(mActivity.camConfig.enableEIS)
1106
+
1107
+ if (mActivity.camConfig.saveVideoAsPreviewed)
1108
+ videoCaptureBuilder.setMirrorMode(MirrorMode .MIRROR_MODE_ON_FRONT_ONLY )
1109
+
1110
+ videoCapture = videoCaptureBuilder.build()
1062
1111
1063
1112
useCaseGroupBuilder.addUseCase(videoCapture!! )
1064
1113
}
@@ -1110,17 +1159,8 @@ class CamConfig(private val mActivity: MainActivity) {
1110
1159
ResolutionSelector .Builder ().setAspectRatioStrategy(aspectRatioStrategy).build()
1111
1160
)
1112
1161
1113
- @androidx.camera.camera2.interop.ExperimentalCamera2Interop
1114
- if (isVideoMode && enableEIS) {
1115
- Camera2Interop .Extender (previewBuilder).setCaptureRequestOption(
1116
- CaptureRequest .CONTROL_VIDEO_STABILIZATION_MODE ,
1117
- CameraMetadata .CONTROL_VIDEO_STABILIZATION_MODE_ON
1118
- )
1119
- } else {
1120
- Camera2Interop .Extender (previewBuilder).setCaptureRequestOption(
1121
- CaptureRequest .CONTROL_VIDEO_STABILIZATION_MODE ,
1122
- CameraMetadata .CONTROL_VIDEO_STABILIZATION_MODE_OFF
1123
- )
1162
+ if (isVideoMode) {
1163
+ previewBuilder.setPreviewStabilizationEnabled(enableEIS)
1124
1164
}
1125
1165
1126
1166
preview = previewBuilder.build().also {
0 commit comments