2

I am using a webrtc sample Code to stream from my Android device to a Webpage. The sample Code does not have the function to Switch the camera. I tried to solve it but I failed. The sample uses a VideoCapturerAndroid class all of the Suggestions I found switching the camera used a different type.

The main part of the sample Looks like this:

@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);

    ....
}

Currently I am hardcoding which camera shall be used:

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

This is my button which shall Switch the camera:

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

I also tried to restart the activity and give a Parameter which tells one that the other camera shall be used, but I would like to Keep the stream fluent and not to restart the activity.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Jaan
  • 251
  • 1
  • 6
  • 16

1 Answers1

5

You are using a very old implementation of WebRTC in android. VideoRendererGui is removed from new WebRTC library. I strongly suggest you to always use the newest version possible of google WebRTC from here which is at the time of writing is 1.0.22512

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

You can check the Android implementation of the newest library from official WebRTC Chromium project site here. Check out the other classes too.

With the new library, you should create a VideoCapturer in the following way.

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

createCameraCapturer() Method :

  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;
    }

and call switchCamera() method from your class whenever you want to switch between front and back camera.

 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
        }
    }
}
Somesh Kumar
  • 8,088
  • 4
  • 33
  • 49