@@ -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
@@ -223,6 +224,10 @@ class CamConfig(private val mActivity: MainActivity) {
223224
224225 var lastCapturedItem: CapturedItem ? = null
225226
227+ private var frontCameraInfo : CameraInfo ? = null
228+
229+ private var rearCameraInfo : CameraInfo ? = null
230+
226231 init {
227232 if (mActivity !is SecureActivity ) {
228233 CapturedItems .init (mActivity, this )
@@ -355,7 +360,7 @@ class CamConfig(private val mActivity: MainActivity) {
355360 modePref.getString(videoFrameRateKey, " " )!!
356361 )
357362 } else {
358- SettingValues . Default . VIDEO_FRAME_RATE
363+ defaultVideoFrameRate
359364 }
360365 }
361366 set(value) {
@@ -377,6 +382,14 @@ class CamConfig(private val mActivity: MainActivity) {
377382 return " ${SettingValues .Key .VIDEO_FRAME_RATE } _$pf "
378383 }
379384
385+ val defaultVideoFrameRate : Range <Int >
386+ get() {
387+ val availableFrameRates = getAvailableVideoFrameRates()
388+ if (availableFrameRates.contains(SettingValues .Default .VIDEO_FRAME_RATE ))
389+ return SettingValues .Default .VIDEO_FRAME_RATE
390+ return availableFrameRates[0 ]
391+ }
392+
380393 var flashMode: Int
381394 get() = if (imageCapture != null ) imageCapture!! .flashMode else
382395 SettingValues .Default .FLASH_MODE
@@ -928,6 +941,24 @@ class CamConfig(private val mActivity: MainActivity) {
928941 startCamera(true )
929942 }
930943
944+ fun getCurrentCameraInfo () : CameraInfo {
945+ return if (lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo!!
946+ else frontCameraInfo!!
947+ }
948+
949+ fun getAvailableVideoFrameRates (): List <Range <Int >> {
950+ val resSet = getCurrentCameraInfo().supportedFrameRateRanges
951+
952+ // Individual fps -> Ranged fps (sorted by lower value of range and then upper for each lower value)
953+ val resList = resSet.sortedWith(compareBy<Range <Int >> { it.lower != it.upper }.thenBy { it.lower }.thenBy { it.upper })
954+
955+ // If the supportedFrameRateRange list is somehow empty due to device/library implementation
956+ // go with the most likely default rate
957+ if (resList.isEmpty()) return listOf (SettingValues .Default .VIDEO_FRAME_RATE )
958+
959+ return resList
960+ }
961+
931962 fun toggleCameraSelector () {
932963
933964 // Manually switch to the opposite lens facing
@@ -971,6 +1002,12 @@ class CamConfig(private val mActivity: MainActivity) {
9711002 return
9721003 }
9731004
1005+ // Select a single camera for front/rear facing
1006+ for (cameraInfo in cameraProvider!! .availableCameraInfos) {
1007+ if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_FRONT ) frontCameraInfo = cameraInfo
1008+ else if (cameraInfo.lensFacing == CameraSelector .LENS_FACING_BACK ) rearCameraInfo = cameraInfo
1009+ }
1010+
9741011 // Manually switch to the other lens facing (if the default lens facing isn't
9751012 // supported for the current device)
9761013 if (! isLensFacingSupported(lensFacing)) {
@@ -997,11 +1034,11 @@ class CamConfig(private val mActivity: MainActivity) {
9971034 }
9981035
9991036 private fun isLensFacingSupported (lensFacing : Int ) : Boolean {
1000- val tCameraSelector = CameraSelector . Builder ()
1001- .requireLensFacing(lensFacing)
1002- .build()
1003-
1004- return cameraProvider?.hasCamera(tCameraSelector) ? : false
1037+ return when (lensFacing) {
1038+ CameraSelector . LENS_FACING_FRONT -> frontCameraInfo != null
1039+ CameraSelector . LENS_FACING_BACK -> rearCameraInfo != null
1040+ else -> false
1041+ }
10051042 }
10061043
10071044 // Start the camera with latest hard configuration
@@ -1026,7 +1063,15 @@ class CamConfig(private val mActivity: MainActivity) {
10261063 if (mActivity.isDestroyed || mActivity.isFinishing) return
10271064
10281065 cameraSelector = CameraSelector .Builder ()
1029- .requireLensFacing(lensFacing)
1066+ .addCameraFilter {
1067+ return @addCameraFilter listOf (
1068+ if (lensFacing == CameraSelector .LENS_FACING_BACK ) {
1069+ rearCameraInfo
1070+ } else {
1071+ frontCameraInfo
1072+ }
1073+ )
1074+ }
10301075 .build()
10311076
10321077 val builder = ImageCapture .Builder ()
0 commit comments