java - VideoCapturer 切换摄像头

标签 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);
}

我还尝试重新启动 Activity 并给出一个参数,告诉一个人应使用另一台相机,但我想保持流流畅而不重新启动 Activity 。

最佳答案

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

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

您可以从官方WebRTC Chromium项目网站here查看最新库的Android实现。也查看其他类(class)。

使用新库,您应该按以下方式创建一个 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
        }
    }
}

关于java - VideoCapturer 切换摄像头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49489353/

相关文章:

java - Eclipse 项目源菜单仅显示 "Format"

java - 为什么在尝试使用 split ("."拆分字符串时打印出一个空数组)

安卓应用引擎java : authenticating users

java - 在新的Android studio中运行时出错

android - Droid 设备 - 不会旋转从相机捕获的图像? (相机.参数)

java - 在 Swing 中绘画

Java:在写入之前检查对象是否存在于对象文件中

java - 通过 JSON 解析器在 GoogleMap V2 上保存当前位置

Android:如何检查设备是否实现了 Camera2 api 功能?

java - 相机拍照旋转