【问题标题】:VideoCapturer switch cameraVideoCapturer 切换摄像头
【发布时间】:2018-09-04 11:21:48
【问题描述】:

我正在使用 webrtc 示例代码从我的 Android 设备流式传输到网页。 示例代码没有切换相机的功能。我试图解决它,但我失败了。该示例使用 VideoCapturerAndroid 类,我发现切换相机的所有建议都使用了不同的类型。

示例的主要部分如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_video_chat);
    ButterKnife.bind(this);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    Bundle extras = getIntent().getExtras();

    if (extras == null || !extras.containsKey(Constants.USER_NAME)) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        Toast.makeText(this, "Need to pass username to VideoChatActivity in intent extras (Constants.USER_NAME).", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
    this.username = extras.getString(Constants.USER_NAME, "");
    this.mCallStatus = (TextView) findViewById(R.id.call_status);

    // First, we initiate the PeerConnectionFactory with our application context and some options.
    PeerConnectionFactory.initializeAndroidGlobals(
            this,  // Context
            true,  // Audio Enabled
            true,  // Video Enabled
            true,  // Hardware Acceleration Enabled
            null); // Render EGL Context

    pcFactory = new PeerConnectionFactory();
    this.pnRTCClient = new PnRTCClient(Constants.PUB_KEY, Constants.SUB_KEY, this.username);
    List<PeerConnection.IceServer> servers = getXirSysIceServers();
    if (!servers.isEmpty()) {
        this.pnRTCClient.setSignalParams(new de.kevingleason.pnwebrtc.PnSignalingParams());
    }

    backFacingCam = VideoCapturerAndroid.getNameOfBackFacingDevice();
    frontFacingCam = VideoCapturerAndroid.getNameOfFrontFacingDevice();

    // Creates a VideoCapturerAndroid instance for the device name
    //VideoCapturer capturer = VideoCapturerAndroid.create(frontFacingCam);
    capturer = VideoCapturerAndroid.create(facingCam);
    // First create a Video Source, then we can make a Video Track
    localVideoSource = pcFactory.createVideoSource(capturer, this.pnRTCClient.videoConstraints());
    localVideoTrack = pcFactory.createVideoTrack(VIDEO_TRACK_ID, localVideoSource);

    // First we create an AudioSource then we can create our AudioTrack
    AudioSource audioSource = pcFactory.createAudioSource(this.pnRTCClient.audioConstraints());
    AudioTrack localAudioTrack = pcFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);

    // To create our VideoRenderer, we can use the included VideoRendererGui for simplicity
    // First we need to set the GLSurfaceView that it should render to
    this.videoView = (GLSurfaceView) findViewById(R.id.gl_surface);

    // Then we set that view, and pass a Runnable to run once the surface is ready
    VideoRendererGui.setView(videoView, null);

    // Now that VideoRendererGui is ready, we can get our VideoRenderer.
    // IN THIS ORDER. Effects which is on top or bottom
    remoteRender = VideoRendererGui.create(0, 0, 100, 100, VideoRendererGui.ScalingType.SCALE_ASPECT_FILL, false);
    localRender = VideoRendererGui.create(0, 0, 100, 100, VideoRendererGui.ScalingType.SCALE_ASPECT_FILL, true);

    // We start out with an empty MediaStream object, created with help from our PeerConnectionFactory
    // Note that LOCAL_MEDIA_STREAM_ID can be any string
    MediaStream mediaStream = pcFactory.createLocalMediaStream(LOCAL_MEDIA_STREAM_ID);

    // Now we can add our tracks.
    mediaStream.addTrack(localVideoTrack);
    mediaStream.addTrack(localAudioTrack);

    // First attach the RTC Listener so that callback events will be triggered
    this.pnRTCClient.attachRTCListener(new DemoRTCListener());

    // Then attach your local media stream to the PnRTCClient.
    //  This will trigger the onLocalStream callback.
    this.pnRTCClient.attachLocalMediaStream(mediaStream);

    this.pnRTCClient.listenOn(username);
    this.pnRTCClient.setMaxConnections(1);

    ....
}

目前我正在硬编码应该使用哪个相机:

    backFacingCam = VideoCapturerAndroid.getNameOfBackFacingDevice(); 
    frontFacingCam = VideoCapturerAndroid.getNameOfFrontFacingDevice();

这是我用来切换相机的按钮:

@OnClick(R.id.switchCameraBtn)
public void switchCameraBtn(View view) {
    Log.e("Test", "switch camera button clicked");
    this.mCallStatus = (TextView) findViewById(R.id.call_status);
}

我还尝试重新启动活动并提供一个参数,告诉一个应该使用另一个摄像头,但我想保持流流畅而不是重新启动活动。

【问题讨论】:

    标签: java android android-camera webrtc video-capture


    【解决方案1】:

    您在 android 中使用了一个非常古老的 WebRTC 实现。 VideoRendererGui 已从新的 WebRTC 库中删除。我强烈建议您始终使用来自here 的最新版本的google WebRTC,在撰写本文时是1.0.22512

    compile 'org.webrtc:google-webrtc:1.0.22512'
    

    您可以从官方 WebRTC Chromium 项目站点here 查看最新库的 Android 实现。也请查看其他课程。

    使用新库,您应该按以下方式创建VideoCapturer

      private void createVideoCapturer() {
        VideoCapturer videoCapturer;
        if (Camera2Enumerator.isSupported(this)) {
            videoCapturer = createCameraCapturer(new Camera2Enumerator(this));
        } else {       
            videoCapturer = createCameraCapturer(new Camera1Enumerator(false));
        }
    }
    

    createCameraCapturer()方法:

      private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
            final String[] deviceNames = enumerator.getDeviceNames();
            // First, try to find front facing camera
            for (String deviceName : deviceNames) {
                if (enumerator.isFrontFacing(deviceName)) {
                    VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
                    if (videoCapturer != null) {
                        return videoCapturer;
                    }
                }
            }
    
            // Front facing camera not found, try something else
            for (String deviceName : deviceNames) {
                if (!enumerator.isFrontFacing(deviceName)) {
                    CameraVideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
                    if (videoCapturer != null) {
                        return videoCapturer;
                    }
                }
            }
    
            return null;
        }
    

    并在您想在前后摄像头之间切换时从您的班级中调用switchCamera() 方法。

     private void switchCamera() {
        if (videoCapturer != null) {
            if (videoCapturer instanceof CameraVideoCapturer) {
                CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer) videoCapturer;
                cameraVideoCapturer.switchCamera(null);
            } else {
               // Will not switch camera, video capturer is not a camera
            }
        }
    }
    

    【讨论】:

    • 您好,感谢您的回答,您有此案例的示例项目吗?
    • 检查我在第二段中提供的链接。下载它。它是 www.appr.tc 的客户端(apprtc 是 webrtc 在 web 和 mobile 上的官方实现)
    • 如何在视频之间点击照片?
    • @VishambarPandey 你可以问一个单独的问题。
    • 这是问题的解决方案,应标记为答案。谢谢。
    猜你喜欢
    • 2016-12-31
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多