import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.TextureView;
import android.widget.FrameLayout;
import com.ss.bytertc.engine.RTCEngine;
import com.ss.bytertc.engine.RTCRoom;
import com.ss.bytertc.engine.RTCRoomConfig;
import com.ss.bytertc.engine.UserInfo;
import com.ss.bytertc.engine.VideoCanvas;
import com.ss.bytertc.engine.data.EngineConfig;
import com.ss.bytertc.engine.data.RemoteStreamKey;
import com.ss.bytertc.engine.data.StreamIndex;
import com.ss.bytertc.engine.handler.IRTCEngineEventHandler;
import com.ss.bytertc.engine.handler.IRTCRoomEventHandler;
import com.ss.bytertc.engine.type.ChannelProfile;
public class MainActivity extends AppCompatActivity {
private static final String APP_ID = "";
private static final String roomId = "";
private static final String userId = "";
private static final String token = "";
private FrameLayout localViewContainer;
private FrameLayout remoteViewContainer;
private RTCEngine rtcEngine;
private RTCRoom rtcRoom;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localViewContainer = findViewById(R.id.local_view_container);
remoteViewContainer = findViewById(R.id.remote_view_container);
((AppCompatButton) findViewById(R.id.btn_join_room)).setOnClickListener(v -> {
((AppCompatButton) findViewById(R.id.btn_leave_room)).setOnClickListener(v -> {
EngineConfig engineConfig = new EngineConfig();
engineConfig.context = this;
engineConfig.appID = APP_ID;
rtcEngine = RTCEngine.createRTCEngine(engineConfig, engineEventHandler);
rtcEngine.startVideoCapture();
rtcEngine.startAudioCapture();
public void requestPermission() {
String[] PERMISSIONS_STORAGE = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, "android.permission.RECORD_AUDIO") != PackageManager.PERMISSION_GRANTED) {
requestPermissions(PERMISSIONS_STORAGE, 22);
private void setLocalRenderView() {
TextureView textureView = new TextureView(this);
localViewContainer.removeAllViews();
localViewContainer.addView(textureView);
VideoCanvas videoCanvas = new VideoCanvas();
videoCanvas.renderView = textureView;
videoCanvas.renderMode = VideoCanvas.RENDER_MODE_HIDDEN;
rtcEngine.setLocalVideoCanvas(videoCanvas);
private void setRemoteRenderView(String streamId) {
TextureView remoteTextureView = new TextureView(this);
remoteViewContainer.removeAllViews();
remoteViewContainer.addView(remoteTextureView);
VideoCanvas videoCanvas = new VideoCanvas();
videoCanvas.renderView = remoteTextureView;
videoCanvas.renderMode = VideoCanvas.RENDER_MODE_HIDDEN;
rtcEngine.setRemoteVideoCanvas(streamId, videoCanvas);
private void removeRemoteView(String streamId) {
rtcEngine.setRemoteVideoCanvas(streamId, null);
IRTCEngineEventHandler engineEventHandler = new IRTCEngineEventHandler() {
IRTCRoomEventHandler rtcRoomEventHandler = new IRTCRoomEventHandler() {
public void onUserPublishStreamVideo(String streamId, StreamInfo streamInfo, boolean isPublish) {
runOnUiThread(() -> setRemoteRenderView(streamInfo.streamId));
runOnUiThread(() -> removeRemoteView(streamInfo.streamId));
private void joinRoom(String roomId) {
rtcRoom = rtcEngine.createRTCRoom(roomId);
rtcRoom.setRTCRoomEventHandler(rtcRoomEventHandler);
UserInfo userInfo = new UserInfo(userId, "");
boolean isAutoPublishAudio = true;
boolean isAutoPublishVideo = true;
boolean isAutoSubscribeAudio = true;
boolean isAutoSubscribeVideo = true;
RTCRoomConfig roomConfig = new RTCRoomConfig(
ChannelProfile.CHANNEL_PROFILE_CHAT_ROOM,
rtcRoom.joinRoom(token, userInfo, true, roomConfig);
private void leaveRoom() {
protected void onDestroy() {
if (rtcEngine != null) {
rtcEngine.stopVideoCapture();
rtcEngine.stopAudioCapture();
RTCEngine.destroyRTCEngine();