@@ -22,6 +22,7 @@ import androidx.annotation.StringRes
2222import androidx.camera.camera2.interop.Camera2Interop
2323import androidx.camera.core.AspectRatio
2424import androidx.camera.core.Camera
25+ import androidx.camera.core.CameraInfo
2526import androidx.camera.core.CameraSelector
2627import androidx.camera.core.ImageAnalysis
2728import androidx.camera.core.ImageCapture
@@ -227,6 +228,10 @@ class CamConfig(private val mActivity: MainActivity) {
227228
228229 var lastCapturedItem: CapturedItem ? = null
229230
231+ private var frontCameraInfo : CameraInfo ? = null
232+
233+ private var rearCameraInfo : CameraInfo ? = null
234+
230235 init {
231236 if (mActivity !is SecureActivity ) {
232237 CapturedItems .init (mActivity, this )
@@ -359,7 +364,7 @@ class CamConfig(private val mActivity: MainActivity) {
359364 modePref.getString(videoFrameRateKey, " " )!!
360365 )
361366 } else {
362- SettingValues . Default . VIDEO_FRAME_RATE
367+ defaultVideoFrameRate
363368 }
364369 }
365370 set(value) {
@@ -381,6 +386,14 @@ class CamConfig(private val mActivity: MainActivity) {
381386 return " ${SettingValues .Key .VIDEO_FRAME_RATE } _$pf "
382387 }
383388
389+ val defaultVideoFrameRate : Range <Int >
390+ get() {
391+ val availableFrameRates = getAvailableVideoFrameRates()
392+ if (availableFrameRates.contains(SettingValues .Default .VIDEO_FRAME_RATE ))
393+ return SettingValues .Default .VIDEO_FRAME_RATE
394+ return availableFrameRates[0 ]
395+ }
396+
384397 var flashMode: Int
385398 get() = if (imageCapture != null ) imageCapture!! .flashMode else
386399 SettingValues .Default .FLASH_MODE
@@ -945,6 +958,24 @@ class CamConfig(private val mActivity: MainActivity) {
945958 startCamera(true )
946959 }
947960
961+ fun getCurrentCameraInfo () : CameraInfo {
962+ return if (lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo!!
963+ else frontCameraInfo!!
964+ }
965+
966+ fun getAvailableVideoFrameRates (): List <Range <Int >> {
967+ val resSet = getCurrentCameraInfo().supportedFrameRateRanges
968+
969+ // Individual fps -> Ranged fps (sorted by lower value of range and then upper for each lower value)
970+ val resList = resSet.sortedWith(compareBy<Range <Int >> { it.lower != it.upper }.thenBy { it.lower }.thenBy { it.upper })
971+
972+ // If the supportedFrameRateRange list is somehow empty due to device/library implementation
973+ // go with the most likely default rate
974+ if (resList.isEmpty()) return listOf (SettingValues .Default .VIDEO_FRAME_RATE )
975+
976+ return resList
977+ }
978+
948979 fun toggleCameraSelector () {
949980
950981 // Manually switch to the opposite lens facing
@@ -988,6 +1019,12 @@ class CamConfig(private val mActivity: MainActivity) {
9881019 return
9891020 }
9901021
1022+ // Select a single camera for front/rear facing
1023+ for (cameraInfo in cameraProvider!! .availableCameraInfos) {
1024+ if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_FRONT ) frontCameraInfo = cameraInfo
1025+ else if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo = cameraInfo
1026+ }
1027+
9911028 // Manually switch to the other lens facing (if the default lens facing isn't
9921029 // supported for the current device)
9931030 if (! isLensFacingSupported(lensFacing)) {
@@ -1014,11 +1051,11 @@ class CamConfig(private val mActivity: MainActivity) {
10141051 }
10151052
10161053 private fun isLensFacingSupported (lensFacing : Int ) : Boolean {
1017- val tCameraSelector = CameraSelector . Builder ()
1018- .requireLensFacing(lensFacing)
1019- .build()
1020-
1021- return cameraProvider?.hasCamera(tCameraSelector) ? : false
1054+ return when (lensFacing) {
1055+ CameraSelector . LENS_FACING_FRONT -> frontCameraInfo != null
1056+ CameraSelector . LENS_FACING_BACK -> rearCameraInfo != null
1057+ else -> false
1058+ }
10221059 }
10231060
10241061 // Start the camera with latest hard configuration
@@ -1043,7 +1080,15 @@ class CamConfig(private val mActivity: MainActivity) {
10431080 if (mActivity.isDestroyed || mActivity.isFinishing) return
10441081
10451082 cameraSelector = CameraSelector .Builder ()
1046- .requireLensFacing(lensFacing)
1083+ .addCameraFilter {
1084+ return @addCameraFilter listOf (
1085+ if (lensFacing == CameraSelector .LENS_FACING_BACK ) {
1086+ rearCameraInfo
1087+ } else {
1088+ frontCameraInfo
1089+ }
1090+ )
1091+ }
10471092 .build()
10481093
10491094 val builder = ImageCapture .Builder ()
0 commit comments