VideoCapturer切换摄像头

时间:2018-03-26 10:33:10

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

我正在使用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);
}

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

1 个答案:

答案 0 :(得分:0)

你在android中使用了一个非常古老的WebRTC实现。从新的WebRTC库中删除VideoRendererGui。我强烈建议您始终使用来自here的最新版本的谷歌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
        }
    }
}