Android : 如何使用 WEBRTC android io.pristine.libjingle:11139 打开手电筒

Posted

技术标签:

【中文标题】Android : 如何使用 WEBRTC android io.pristine.libjingle:11139 打开手电筒【英文标题】:Android : How to turn on FLASHLIGHT using WEBRTC android io.pristine.libjingle:11139 【发布时间】:2018-07-13 21:40:43 【问题描述】:

伟大的开发者。 我正在使用 io.pristine.libjingle:11139 的 webRTC 库进行视频通话。 一切顺利,现在我只想打开手电筒,我研究了几乎所有与手电筒有关的问题,我发现手电筒是相机的一项功能,所以要打开手电筒必须与CAMERA对象一起使用. 现在我卡在这里,因为我正在使用该库,它不允许我访问已经打开的相机对象。 那么如何在不使用相机的情况下打开手电筒,因为 webrtc 库已经使用了相机? 是否有任何其他最新的库允许访问 libjingle for webrtc for android 的相机对象?

我需要帮助,这是一个非常好的挑战。

问候, 佛法

【问题讨论】:

不,我已阅读此问题,我无权访问相机对象,但我的应用程序中的 webrtc 库已经使用了它。 @Amit Vaghela 你能告诉我这个问题,这样我就能得到答案,这将是很大的帮助。 以上链接不适合你? 亲爱的阿米特,我正在使用 WEBRTC 库并打开摄像头,但没有将其作为公共提供,因此我无法在已打开的摄像头上设置任何内容。你知道WEBRTC吗? 【参考方案1】:

我今天遇到了这个问题,但在任何地方都没有找到解决方案,所以我想分享我的解决方案,尽管在提出问题之后已经很晚了。基本上有两种选择:修改源代码并自己编译 webrtc 库,或者更简单的解决方案 - 稍微覆盖库的功能。我不得不说我使用的是直接来自 Google 存储库的最新预建库,所以我的 libjingle 库可能有点不同。

implementation 'org.webrtc:google-webrtc:1.0.28262'

现在,到代码本身。创建一个包org.webrtc,以便能够访问您需要实现或修改的包私有类和接口。

首先是interface CameraSession。此接口的实例处理对 android 的 Camera 的访问。所以我通过从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);
    

下一步是修改VideoCapturer用来获取摄像头的VideoFrames。为此,我通过扩展 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);
    

现在您可以简单地使用新修改的相机枚举器来获取可以控制手电筒的相机捕捉器实例。

希望这会有所帮助:)

【讨论】:

能否请您分享完整的源代码或任何链接,我已遵循所有这些步骤。但无法打开闪光灯。【参考方案2】:

为了妥协 @Dzerjrin 的回答,我终于将 Flashlight 功能实现到基于 WebRTC 的 Android 应用程序中。

首先,我使用的是WebRTC库的Gradle依赖;

implementation 'org.webrtc:google-webrtc:1.0.32006'

按照建议,为了访问包私有类,我们需要创建一个包org.webrtc

那么我们需要create三个类FlashlightCameraCapturerFlashlightCameraNumeratorFlaslightCameraSession

该功能的主要技巧是,在您现有的 VideoChat 类中使用创建的 CameraNumerator,如下所示;然后你可以使用手电筒。在下面的场景中,使用了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
    

【讨论】:

以上是关于Android : 如何使用 WEBRTC android io.pristine.libjingle:11139 打开手电筒的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter(Android 和 Ios)中实现与 WebRTC 的电话会议视频聊天

如何正确地在android上计算webrtc

使用webrtc for android,如何在视频通话中保存图片?

如何在 Android webRTC 上启用 H264

Android技术分享| Android WebRTC 对 AudioRecord 的使用

如何使用适用于 Android 的 WebRTC Native Code 实现 3 路电话会议视频聊天?