伟大的开发人员。 我正在使用io.pristine.libjingle:11139的webRTC库进行视频通话。 一切都很顺利,现在我只想打开手电筒,我研究了几乎所有与手电筒有关的问题,我发现手电筒是相机的一个功能,所以要打开手电筒必须使用相机对象。 现在我卡在这里,因为我正在使用库,它不允许我访问已经打开的相机对象。 那么如何在不使用相机的情况下打开手电筒,因为相机已经被webrtc库使用了? 有没有其他最新的库允许访问 libjingle for webrtc for android 的相机对象?
我需要帮助,这是一个非常像挑战的人。
问候 佛法
我今天遇到了这个问题,但在任何地方都没有找到解决方案,所以我想分享我的解决方案,尽管在提出问题后已经很晚了。基本上有两种选择:自己修改源代码和编译webrtc库,或者更简单的解决方案 - 稍微覆盖一下库的功能。我不得不说,我使用的是直接从Google存储库中获取的最新预构建库,因此我的libjingle库可能有点不同。
implementation 'org.webrtc:google-webrtc:1.0.28262'
现在,到代码本身。创建一个包org.webrtc
,以便能够访问需要实现或修改的包私有类和接口。
首先是interface CameraSession
.此接口的实例处理对安卓相机的访问。因此,我通过从class Camera1Session
复制粘贴代码并添加一个打开/关闭手电筒的功能来创建class FlaslightCameraSession implements CameraSession
,如下所示。
void setFlashlightActive(boolean isActive) {
Camera.Parameters params = camera.getParameters();
if (isActive) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
camera.setParameters(params);
}
下一步是修改用于获取相机VideoFrame
VideoCapturer
。为此,我只需通过扩展webrtc的class Camera1Capturer
进行class FlashlightCameraCapturer
,并添加简单的修改来控制手电筒。
@Override
protected void createCameraSession(CameraSession.CreateSessionCallback createSessionCallback, CameraSession.Events events, Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, String cameraName, int width, int height, int framerate) {
CameraSession.CreateSessionCallback myCallback = new CameraSession.CreateSessionCallback() {
@Override
public void onDone(CameraSession cameraSession) {
FlashlightCameraCapturer.this.cameraSession = (FlashlightCameraSession) cameraSession;
createSessionCallback.onDone(cameraSession);
}
@Override
public void onFailure(CameraSession.FailureType failureType, String s) {
createSessionCallback.onFailure(failureType, s);
}
};
FlashlightCameraSession.create(myCallback, events, captureToTexture, applicationContext, surfaceTextureHelper, Camera1Enumerator.getCameraIndex(cameraName), width, height, framerate);
}
public void turnOnFlashlight() {
cameraSession.setFlashlightActive(true);
}
public void turnOffFlashlight() {
cameraSession.setFlashlightActive(false);
}
最后一步是修改CameraEnumerator
。具体来说,您需要覆盖 createCapturer 函数来创建我们修改后的捕获器的实例。所以我扩展了class Camera1Enumerator
来覆盖这个函数,如下所示。
@Override
public CameraVideoCapturer createCapturer(String deviceName, CameraVideoCapturer.CameraEventsHandler eventsHandler) {
return new FlashlightCameraCapturer(deviceName, eventsHandler, true);
}
现在,您只需使用新修改的相机枚举器即可获取可以控制手电筒的相机捕获器的实例。
希望这对:)有所帮助
为了妥协@Dzerjrin的答案,我最终将手电筒功能实现到基于WebRTC的Android应用程序中。
首先,我使用的是 WebRTC 库的 Gradle 依赖项;
implementation 'org.webrtc:google-webrtc:1.0.32006'
正如建议的那样,为了访问包私有类,我们需要创建一个包org.webrtc
然后我们需要创建三个类FlashlightCameraCapturer
、FlashlightCameraNumerator
和FlaslightCameraSession
。
该功能的主要技巧是,在现有的视频聊天类中使用创建的相机分子,如下所示;然后你可以使用手电筒。在下面的场景中,使用了FlashlightCameraNumerator
。
private fun createCameraCapturer(enumerator: FlashlightCameraNumerator): FlashlightCameraCapturer? {
val deviceNames = enumerator.deviceNames
if (expertOfTheCall) {
// First, try to find front facing camera
Logging.d(RtcAppConstant.TAG, "Looking for front facing cameras.")
for (i in deviceNames.indices) {
val deviceName = deviceNames[i]
if (enumerator.isFrontFacing(deviceName)) {
Logging.d(RtcAppConstant.TAG, "Creating front facing camera capturer.")
val videoCapturer: FlashlightCameraCapturer? = enumerator.createCapturer(deviceName, null) as FlashlightCameraCapturer?
cameraDeviceId = i
cameraDeviceName = deviceName
if (videoCapturer != null) {
return videoCapturer
}
}
}
// Front facing camera not found, try something else
Logging.d(RtcAppConstant.TAG, "Looking for other cameras.")
for (i in deviceNames.indices) {
val deviceName = deviceNames[i]
if (!enumerator.isFrontFacing(deviceName)) {
Logging.d(RtcAppConstant.TAG, "Creating other camera capturer.")
val videoCapturer: FlashlightCameraCapturer? = enumerator.createCapturer(deviceName, null) as FlashlightCameraCapturer?
cameraDeviceId = i
cameraDeviceName = deviceName
if (videoCapturer != null) {
return videoCapturer
}
}
}
} else {
// First, try to find back camera
Logging.d(RtcAppConstant.TAG, "Looking for other cameras.")
for (i in deviceNames.indices) {
val deviceName = deviceNames[i]
if (!enumerator.isFrontFacing(deviceName)) {
Logging.d(RtcAppConstant.TAG, "Creating other camera capturer.")
val videoCapturer: FlashlightCameraCapturer? = enumerator.createCapturer(deviceName, null) as FlashlightCameraCapturer?
cameraDeviceId = i
cameraDeviceName = deviceName
if (videoCapturer != null) {
return videoCapturer
}
}
}
// Back camera not found, try something else
Logging.d(RtcAppConstant.TAG, "Looking for front facing cameras.")
for (i in deviceNames.indices) {
val deviceName = deviceNames[i]
if (enumerator.isFrontFacing(deviceName)) {
Logging.d(RtcAppConstant.TAG, "Creating front facing camera capturer.")
val videoCapturer: FlashlightCameraCapturer? = enumerator.createCapturer(deviceName, null) as FlashlightCameraCapturer?
cameraDeviceId = i
cameraDeviceName = deviceName
if (videoCapturer != null) {
return videoCapturer
}
}
}
}
return null
}