Suggestions

close search

Back to Custom Camera Video Capturing Overview

Custom Audio Driver Step 2: Configuration

  1. 1
    Custom Camera Video Capturing Step 1:
    Implementation
  2. 2
    Custom Camera Video Capturing Step 2:
    Configuration

To see the code for this sample, switch to the camera-capturer branch of the learning-opentok-android repo:

git checkout camera-capturer

This page shows the difference between this branch and the basic-capturer branch, which this branch builds from.

This branch shows you how to use a custom video capturer using the device camera as the video source.

Before studying this sample, see the basic-capturer sample.

In the initializePublisher() method of the ChatActivity class, after creating a Publisher object, the code calls the setCapturer(capturer) method of the Publisher object, passing in a CameraVideoCapturer object as a parameter:

mPublisher.setCapturer(new CameraVideoCapturer(this, 640, 480, 30));

CameraVideoCapturer is a custom class that extends the BaseVideoCapturer class (defined in the OpenTok iOS SDK). This class lets you define a custom video capturer to be used by an OpenTok publisher. The CameraVideoCapturer class uses a FrontCameraFrameProvider object to capture frames from the Android camera:

public CameraVideoCapturer(Context context, int width, int height, int fps) {
    mWidth = width;
    mHeight = height;
    mDesiredFps = fps;

    mHelper = new FrontCameraFrameProvider(context, mWidth, mHeight, mDesiredFps);
    mHelper.setHelperListener(this);
}

The FrontCameraFrameProvider class uses a FrontCameraFrameProvider.ProviderListener interface to send events when frames are available for capture. The CameraVideoCapturer class implements this interface and its cameraFrameReady() method.

The BaseVideoCapturer.init() method initializes capture settings to be used by the custom video capturer. In this sample's custom implementation of BaseVideoCapturer (CameraVideoCapturer) the initCapture() it also calls the init() method of the FrontCameraFrameProvider class:

@Override
public void init() {
    mCapturerHasStarted = false;
    mCapturerIsPaused = false;

    mCapturerSettings = new CaptureSettings();
    mCapturerSettings.height = mHeight;
    mCapturerSettings.width = mWidth;
    mCapturerSettings.expectedDelay = 0;
    mCapturerSettings.format = BaseVideoCapturer.NV21;

    mHelper.init();
}

The FrontCameraFrameProvider.init() method creates a Camera object.

The BaseVideoCapturer.startCapture() method of is called when a Publisher using the video capturer starts capturing video to send as a stream to the OpenTok session. This will occur after the Session.publish(publisher) method is called. The CameraVideoCapturer of this method calls the startCapture() method of the FrontCameraFrameProvider object:

@Override
public int startCapture() {
    mCapturerHasStarted = true;
    mHelper.startCapture();
    return 0;
}

The FrontCameraFrameProvider.startCapture() method sets some parameters of the Android Camera, based on parameters set at initialization. It creates a callback buffer for the camera (calling the Camera.addCallbackBuffer(buffer) method). It also sets itself as the implementer of the Camera.PreviewCallback interface, and it calls the startPreview() method of the Camera object:

mCamera.setPreviewCallbackWithBuffer(this);
mCamera.startPreview();

The FrontCameraFrameProvider implementation of the FrontCameraFrameProvider.onPreviewFrame(data, camera) method. This method is called when preview frames are displayed by the camera. The FrontCameraFrameProvider calls the cameraFrameReady() method of the ProviderListener object, which is the CameraVideoCapturer object in this app:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    mPreviewBufferLock.lock();
    if (data.length == mExpectedFrameSize) {
        // Get the rotation of the camera
        int currentRotation = compensateCameraRotation(mCurrentDisplay
                .getRotation());

        if (mListener != null) {
            mListener.cameraFrameReady(data, mCaptureActualWidth, mCaptureActualHeight,
                    currentRotation, isFrontCamera());
        }

        // Reuse the video buffer
        camera.addCallbackBuffer(data);
    }
    mPreviewBufferLock.unlock();
}

The CameraVideoCapturer implementation of the cameraFrameReady() method (defined by the Camera.PreviewCallback interface) calls the provideByteArrayFrame() method, defined by the BaseVideoCapturer class (which the CameraVideoCapturer class extends):

@Override
public void cameraFrameReady(byte[] data, int width, int height, int rotation, boolean mirror) {
    provideByteArrayFrame(data, NV21, width,
            height, rotation, mirror);
}

This sends a byte array of data to the publisher, to be used for the next video frame published.

Note that the CameraVideoCapturer also includes code for determining which camera is being used, working with the camera orientation and rotation, and determining the image size.

  1. 1
    Custom Camera Video Capturing Step 1:
    Implementation
  2. 2
    Custom Camera Video Capturing Step 2:
    Configuration