Quickstart

Use an introductory paragraph to explain what the customer is implementing, preferably with a diagram or screenshot.

Example

The following figure shows the workflow of a video call implemented by the Agora SDK. Agora video call

Project setup

Must-have:

  • Describe how to get your extension package, and specify the location of the package in the customer’s project folder.

  • Describe how to get an api key and api secret for using your extension.

Optional:

Other setup that is required to use your extension, if any.

Example

Follow the steps to create the environment necessary to integrate the extension into your app:

  1. Save the agora-simple-filter.aar file to /app/libs in your project folder.

  2. In /Gradle Scripts/build.gradle(Module: <ProjectName> app), add the following line under dependencies:

    implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
    

Implement the extension in your project

Must-have:

Use subsections to break down the procedure. The subsections must:

  • Show how to add your extension using addExtension. Briefly explain all parameters.

  • Show how to enable your extension using enableExtension. Briefly explain all parameters.

  • Show how to use the features of your extension using setExtensionProperty, including passing in the api key and api secret. Briefly explain all parameters.

  • Show how to handle event callbacks from your extension using onEvent. Briefly explain all parameters.

  • Show how to stop or disable your extension. Briefly explain all parameters.

  • Give a runnable code sample that combines the above-mentioned steps as well as the steps to start a video call using the Agora SDK. Be sure to add comments for significant steps.

Optional:

Other steps required to use your extension, if any.

Example for a runnable code sample

Refer to the following code to modify app/src/main/java/com.example.<projectname>/MainActivity:

package com.example.extension;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.view.SurfaceView;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import io.agora.extension.ExtensionManager;
import io.agora.rtc2.Constants;
import io.agora.rtc2.IMediaExtensionObserver;
import io.agora.rtc2.IRtcEngineEventHandler;
import io.agora.rtc2.RtcEngine;
import io.agora.rtc2.RtcEngineConfig;
import io.agora.rtc2.video.VideoCanvas;

import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity {

    private String appId = "Pass in your App ID here";
    private String channelName = "Pass in your channel name here";
    private String token = "Pass in your token here";

    private static final int PERMISSION_REQ_ID = 22;

    private static final String[] REQUESTED_PERMISSIONS = {
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA
    };

    private boolean checkSelfPermission(String permission, int requestCode) {
        if (ContextCompat.checkSelfPermission(this, permission) !=
                PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
            return false;
        }
        return true;
    }

    private RtcEngine mRtcEngine;

    private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
        @Override
        public void onUserJoined(int uid, int elapsed) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setupRemoteVideo(uid);
                }
            });
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
                checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
            initializeAndJoinChannel();
        }
    }

    protected void onDestroy() {
        super.onDestroy();

        mRtcEngine.leaveChannel();
        mRtcEngine.destroy();
    }

    private void initializeAndJoinChannel() {
        try {
            RtcEngineConfig config = new RtcEngineConfig();
            config.mContext = this;
            config.mAppId = appId;
            // Add the extension
            config.addExtension(ExtensionManager.EXTENSION_NAME);
            config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
            config.mEventHandler = mRtcEventHandler;
            mRtcEngine = RtcEngine.create(config);
        } catch (Exception e) {
            throw new RuntimeException("Check the error. " + e.toString());
        }

        mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
        // Enable the extension
        mRtcEngine.enableExtension(ExtensionManager.EXTENSION_VENDOR_NAME, ExtensionManager.EXTENSION_VIDEO_FILTER_NAME, true);

        mRtcEngine.enableVideo();

        FrameLayout container = findViewById(R.id.local_video_view_container);
        SurfaceView surfaceView = new SurfaceView(getBaseContext());
        container.addView(surfaceView);
        mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, 0));

        mRtcEngine.startPreview();

        mRtcEngine.joinChannel(token, channelName, "", 0);

        // Set extension parameters
        JSONObject o = new JSONObject();
        try {
            o.put("plugin.watermask.wmStr", "chenmeng");
            o.put("plugin.watermask.wmEffectEnabled", true);

            // Use the extension to add a watermark for local video
            mRtcEngine.setExtensionProperty(ExtensionManager.EXTENSION_VENDOR_NAME, ExtensionManager.EXTENSION_VIDEO_FILTER_NAME, "key", o.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }


    }

    private void setupRemoteVideo(int uid) {
        FrameLayout container = findViewById(R.id.remote_video_view_container);
        SurfaceView surfaceView = RtcEngine.CreateRendererView(getBaseContext());
        surfaceView.setZOrderMediaOverlay(true);
        container.addView(surfaceView);
        mRtcEngine.setupRemoteVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid));
    }

}