Reputation: 5
So I have a requirement of recording both front and back camera at once. I even have this feature in my phone's camera application. So i thought maybe I can develop and application too to achieve this functionality.
First I tried using react-native, it failed to create 2 views for 2 separate cameras by showing a message "Camera already in use". Then after a little bit research, I got to know react-native cannot do that and we have to write native code for CameraX or Camera2 libraries. Attached code for reference.
import {
useCameraDevices,
Camera,
useCameraDevice,
useCameraPermission,
} from "react-native-vision-camera";
import { View, Button, Text } from "react-native";
import { useEffect, useState } from "react";
const DualCameraScreen = () => {
const device1 = useCameraDevice("front");
const device2 = useCameraDevice("back");
const { hasPermission, requestPermission } = useCameraPermission();
const [isRecording, setIsRecording] = useState(false);
if (!hasPermission) {
requestPermission();
}
const startRecording = async () => {
setIsRecording(true);
};
return (
<View style={{ flex: 1 }}>
{device1 && device2 && (
<View
style={{ flex: 1, flexDirection: "column", backgroundColor: "green" }}
>
<Camera
style={{ flex: 1 / 3, width: "100%" }}
device={device1}
isActive={true}
video={true}
/>
<Camera
style={{ flex: 1 / 3, width: "100%" }}
device={device2}
isActive={true}
/>
</View>
)}
</View>
);
};
export default DualCameraScreen;
Coming back to android studio (kotlin), started developing the same thing and again stuck on the same thing, This time since I was on native mode, I had access to more logs, which showed me that phone's maximum allowed cameras is 1. Code attached below:
implementation "androidx.camera:camera-core:1.4.1"
implementation "androidx.camera:camera-camera2:1.4.1"
implementation "androidx.camera:camera-lifecycle:1.4.1"
implementation "androidx.camera:camera-view:1.4.1"
class DualCameraActivity : AppCompatActivity() {
private lateinit var backCameraPreview: PreviewView
private lateinit var frontCameraPreview: PreviewView
private var cameraProvider: ProcessCameraProvider? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dual_camera)
backCameraPreview = findViewById(R.id.backCameraPreview)
frontCameraPreview = findViewById(R.id.frontCameraPreview)
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
bindDualCameras()
}, ContextCompat.getMainExecutor(this))
}
private fun bindDualCameras() {
val cameraProvider = cameraProvider ?: return
val cameraSelectorBack = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
val cameraSelectorFront = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
.build()
val previewBack = Preview.Builder().build().also {
it.setSurfaceProvider(backCameraPreview.surfaceProvider)
}
val previewFront = Preview.Builder().build().also {
it.setSurfaceProvider(frontCameraPreview.surfaceProvider)
}
// Unbind any previously bound use cases
cameraProvider.unbindAll()
try {
// Bind both cameras
cameraProvider.bindToLifecycle(this, cameraSelectorBack, previewBack)
cameraProvider.bindToLifecycle(this, cameraSelectorFront, previewFront)
} catch (exc: Exception) {
Log.e("DualCameraActivity", "Use case binding failed", exc)
}
}
}
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.camera.view.PreviewView
android:id="@+id/backCameraPreview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/frontCameraPreview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.camera.view.PreviewView
android:id="@+id/frontCameraPreview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/backCameraPreview"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now after a bit of more research, I got the following code:
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraIdList = cameraManager.cameraIdList
for (id in cameraIdList) {
val characteristics = cameraManager.getCameraCharacteristics(id)
val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
if (capabilities != null && capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) {
Log.d("CameraInfo", "Device supports concurrent camera: $id")
}
}
this code REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
tells if phone can handle multiple cameras or not and the above code failed to print anything which shows my phone cannot allow custom made applications to do this. I researched more and got to know that only Snapdragon chipsets can handle this. I checked on a phone with Snapdragon 730 and it failed but with Snapdragon 860 it worked.
So I want to know what kind of issue is this, is this only allowed on Snapdragons 800+ because it fails on latest MediaTeks (which actually has access to dual mode in camera app).
Upvotes: 0
Views: 63
Reputation: 18137
REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA
is not about using the front and back cameras at the same time; it's about camera clusters such as telephoto + wide + ultrawide combinations that are often used on back cameras especially. Devices that support this capability allow access to these individual cameras, instead of either hiding them or only allowing access to a composite logical camera.
What you want to use is either ConcurrentCamera from CameraX, or if using camera2 directly, you'd need to follow the information at PackageManager.FEATURE_CAMERA_CONCURRENT.
In any case, the presence of FEATURE_CAMERA_CONCURRENT will tell you if the device officially supports simultaneous access to the back and front cameras for regular Android apps.
Upvotes: 0