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


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

最佳答案

您正在使用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
        }
    }
}

07-28 01:14
查看更多