Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Unacceptable certificate error in webrtc video chat application #690

Open
raghugunda opened this issue Nov 11, 2020 · 1 comment
Open

Unacceptable certificate error in webrtc video chat application #690

raghugunda opened this issue Nov 11, 2020 · 1 comment

Comments

@raghugunda
Copy link

raghugunda commented Nov 11, 2020

Screenshot_2020-11-11-10-53-13-849_com skillatwill skillatwill

**I'm building video chat application using webrtc. when i started video call some error is coming. how to resolve that issue.

E/RoomRTCClient: Room connection error: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB

E/WSRTCClient: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB**

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.UiThread;

import com.skillatwill.skillatwill.R;

import org.appspot.apprtc.AppRTCClient;
import org.appspot.apprtc.PeerConnectionClient;
import org.appspot.apprtc.WebSocketRTCClient;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
import org.webrtc.IceCandidate;
import org.webrtc.Logging;
import org.webrtc.RendererCommon.ScalingType;
import org.webrtc.SessionDescription;
import org.webrtc.StatsReport;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFrame;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSink;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

/**

  • Activity for peer connection call setup, call waiting

  • and call view.
    */
    public class CallActivity extends Activity implements AppRTCClient.SignalingEvents,
    PeerConnectionClient.PeerConnectionEvents {
    private static final String TAG = "CallActivity";
    private static final String APPRTC_URL = "https://appr.tc";
    private static final String UPPER_ALPHA_DIGITS = "ACEFGHJKLMNPQRUVWXY123456789";

    // Peer connection statistics callback period in ms.
    private static final int STAT_CALLBACK_PERIOD = 1000;
    private final ProxyRenderer remoteProxyRenderer = new ProxyRenderer();
    private final ProxyVideoSink localProxyVideoSink = new ProxyVideoSink();
    private final List<VideoRenderer.Callbacks> remoteRenderers = new ArrayList<>();
    private PeerConnectionClient peerConnectionClient = null;
    private AppRTCClient appRtcClient;
    private AppRTCClient.SignalingParameters signalingParameters;
    private SurfaceViewRenderer pipRenderer;
    private SurfaceViewRenderer fullscreenRenderer;
    private Toast logToast;
    private boolean activityRunning;
    private AppRTCClient.RoomConnectionParameters roomConnectionParameters;
    private PeerConnectionClient.PeerConnectionParameters peerConnectionParameters;
    private boolean iceConnected;
    private boolean isError;
    private long callStartedTimeMs = 0;
    private boolean micEnabled = true;
    private boolean isSwappedFeeds;
    // Control buttons for limited UI
    private ImageButton disconnectButton;
    private ImageButton cameraSwitchButton;
    private ImageButton toggleMuteButton;

    @OverRide
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     setContentView(R.layout.activity_call);
    
     iceConnected = false;
     signalingParameters = null;
    
     // Create UI controls.
     pipRenderer = findViewById(R.id.pip_video_view);
     fullscreenRenderer = findViewById(R.id.fullscreen_video_view);
    
     disconnectButton = findViewById(R.id.button_call_disconnect);
     cameraSwitchButton = findViewById(R.id.button_call_switch_camera);
     toggleMuteButton = findViewById(R.id.button_call_toggle_mic);
    
     // Add buttons click events.
     disconnectButton.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
             onCallHangUp();
         }
     });
    
     cameraSwitchButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             onCameraSwitch();
         }
     });
    
     toggleMuteButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             boolean enabled = onToggleMic();
             toggleMuteButton.setAlpha(enabled ? 1.0f : 0.3f);
         }
     });
    
     // Swap feeds on pip view click.
     pipRenderer.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
             setSwappedFeeds(!isSwappedFeeds);
         }
     });
    
     remoteRenderers.add(remoteProxyRenderer);
    
     // Create peer connection client.
     peerConnectionClient = new PeerConnectionClient();
    
     // Create video renderers.
     pipRenderer.init(peerConnectionClient.getRenderContext(), null);
     pipRenderer.setScalingType(ScalingType.SCALE_ASPECT_FIT);
    
     fullscreenRenderer.init(peerConnectionClient.getRenderContext(), null);
     fullscreenRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL);
    
     pipRenderer.setZOrderMediaOverlay(true);
     pipRenderer.setEnableHardwareScaler(true /* enabled */);
     fullscreenRenderer.setEnableHardwareScaler(true /* enabled */);
     // Start with local feed in fullscreen and swap it to the pip when the call is connected.
     setSwappedFeeds(true /* isSwappedFeeds */);
    
     // Generate a random room ID with 7 uppercase letters and digits
     String randomRoomID = randomString(7, UPPER_ALPHA_DIGITS);
     // Show the random room ID so that another client can join from https://appr.tc
     TextView roomIdTextView = findViewById(R.id.roomID);
    
    
    
     roomIdTextView.setText(getString(R.string.room_id_caption) + randomRoomID);
    
     Log.d(TAG, getString(R.string.room_id_caption) + randomRoomID);
    
     // Connect video call to the random room
     connectVideoCall(randomRoomID);
    

    }

    // Create a random string
    private String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
    int randomInt = new SecureRandom().nextInt(characterSet.length());
    sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
    }

    // Join video call with randomly generated roomId
    private void connectVideoCall(String roomId) {
    Uri roomUri = Uri.parse(APPRTC_URL);

     int videoWidth = 0;
     int videoHeight = 0;
    
     peerConnectionParameters =
             new PeerConnectionClient.PeerConnectionParameters(true,
                     false,
                     false,
                     videoWidth,
                     videoHeight,
                     0,
                     Integer.parseInt(getString(R.string.pref_maxvideobitratevalue_default)),
                     getString(R.string.pref_videocodec_default),
                     true,
                     false,
                     Integer.parseInt(getString(R.string.pref_startaudiobitratevalue_default)),
                     getString(R.string.pref_audiocodec_default),
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     null);
    
     // Create connection client. Use the standard WebSocketRTCClient.
     // DirectRTCClient could be used for point-to-point connection
     appRtcClient = new WebSocketRTCClient(this);
     // Create connection parameters.
     roomConnectionParameters =
             new AppRTCClient.RoomConnectionParameters(
                     roomUri.toString(),
                     roomId,
                     false,
                     null);
    
     peerConnectionClient.createPeerConnectionFactory(
             getApplicationContext(), peerConnectionParameters, CallActivity.this);
    
     startCall();
    

    }

    public void onCallHangUp() {
    disconnect();
    }

    public void onCameraSwitch() {
    if (peerConnectionClient != null) {
    peerConnectionClient.switchCamera();
    }
    }

    public boolean onToggleMic() {
    if (peerConnectionClient != null) {
    micEnabled = !micEnabled;
    peerConnectionClient.setAudioEnabled(micEnabled);
    }
    return micEnabled;
    }

    private void startCall() {
    if (appRtcClient == null) {
    Log.e(TAG, "AppRTC client is not allocated for a call.");
    return;
    }
    callStartedTimeMs = System.currentTimeMillis();

     // Start room connection.
     logAndToast(getString(R.string.connecting_to, roomConnectionParameters.roomUrl));
     appRtcClient.connectToRoom(roomConnectionParameters);
    

    }

    @UiThread
    private void callConnected() {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    Log.i(TAG, "Call connected: delay=" + delta + "ms");
    if (peerConnectionClient == null || isError) {
    Log.w(TAG, "Call is connected in closed or error state");
    return;
    }
    // Enable statistics callback.
    peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
    setSwappedFeeds(false /* isSwappedFeeds */);
    }

    // Disconnect from remote resources, dispose of local resources, and exit.
    private void disconnect() {
    activityRunning = false;
    remoteProxyRenderer.setTarget(null);
    localProxyVideoSink.setTarget(null);
    if (appRtcClient != null) {
    appRtcClient.disconnectFromRoom();
    appRtcClient = null;
    }
    if (pipRenderer != null) {
    pipRenderer.release();
    pipRenderer = null;
    }
    if (fullscreenRenderer != null) {
    fullscreenRenderer.release();
    fullscreenRenderer = null;
    }
    if (peerConnectionClient != null) {
    peerConnectionClient.close();
    peerConnectionClient = null;
    }
    if (iceConnected && !isError) {
    setResult(RESULT_OK);
    } else {
    setResult(RESULT_CANCELED);
    }
    finish();
    }

    private void disconnectWithErrorMessage(final String errorMessage) {
    if (!activityRunning) {
    Log.e(TAG, "Critical error: " + errorMessage);
    disconnect();
    } else {
    new AlertDialog.Builder(this)
    .setTitle(getText(R.string.channel_error_title))
    .setMessage(errorMessage)
    .setCancelable(false)
    .setNeutralButton(R.string.ok,
    new DialogInterface.OnClickListener() {
    @OverRide
    public void onClick(DialogInterface dialog, int id) {
    dialog.cancel();
    disconnect();
    }
    })
    .create()
    .show();
    }
    }

    // Log |msg| and Toast about it.
    private void logAndToast(String msg) {
    Log.d(TAG, msg);
    if (logToast != null) {
    logToast.cancel();
    }
    logToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
    logToast.show();
    }

    private void reportError(final String description) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (!isError) {
    isError = true;
    disconnectWithErrorMessage(description);
    }
    }
    });
    }

    // Create VideoCapturer
    private VideoCapturer createVideoCapturer() {
    final VideoCapturer videoCapturer;
    Logging.d(TAG, "Creating capturer using camera2 API.");
    videoCapturer = createCameraCapturer(new Camera2Enumerator(this));
    if (videoCapturer == null) {
    reportError("Failed to open camera");
    return null;
    }
    return videoCapturer;
    }

    // Create VideoCapturer from camera
    private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
    final String[] deviceNames = enumerator.getDeviceNames();

     // First, try to find front facing camera
     Logging.d(TAG, "Looking for front facing cameras.");
     for (String deviceName : deviceNames) {
         if (enumerator.isFrontFacing(deviceName)) {
             Logging.d(TAG, "Creating front facing camera capturer.");
             VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
    
             if (videoCapturer != null) {
                 return videoCapturer;
             }
         }
     }
    
     // Front facing camera not found, try something else
     Logging.d(TAG, "Looking for other cameras.");
     for (String deviceName : deviceNames) {
         if (!enumerator.isFrontFacing(deviceName)) {
             Logging.d(TAG, "Creating other camera capturer.");
             VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
    
             if (videoCapturer != null) {
                 return videoCapturer;
             }
         }
     }
    
     return null;
    

    }

    private void setSwappedFeeds(boolean isSwappedFeeds) {
    Logging.d(TAG, "setSwappedFeeds: " + isSwappedFeeds);
    this.isSwappedFeeds = isSwappedFeeds;
    localProxyVideoSink.setTarget(isSwappedFeeds ? fullscreenRenderer : pipRenderer);
    remoteProxyRenderer.setTarget(isSwappedFeeds ? pipRenderer : fullscreenRenderer);
    fullscreenRenderer.setMirror(isSwappedFeeds);
    pipRenderer.setMirror(!isSwappedFeeds);
    }

    // -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
    // All callbacks are invoked from websocket signaling looper thread and
    // are routed to UI thread.
    private void onConnectedToRoomInternal(final AppRTCClient.SignalingParameters params) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;

     signalingParameters = params;
     logAndToast("Creating peer connection, delay=" + delta + "ms");
     VideoCapturer videoCapturer = null;
     if (peerConnectionParameters.videoCallEnabled) {
         videoCapturer = createVideoCapturer();
     }
     peerConnectionClient.createPeerConnection(
             localProxyVideoSink, remoteRenderers, videoCapturer, signalingParameters);
    
     if (signalingParameters.initiator) {
         logAndToast("Creating OFFER...");
         // Create offer. Offer SDP will be sent to answering client in
         // PeerConnectionEvents.onLocalDescription event.
         peerConnectionClient.createOffer();
     } else {
         if (params.offerSdp != null) {
             peerConnectionClient.setRemoteDescription(params.offerSdp);
             logAndToast("Creating ANSWER...");
             // Create answer. Answer SDP will be sent to offering client in
             // PeerConnectionEvents.onLocalDescription event.
             peerConnectionClient.createAnswer();
         }
         if (params.iceCandidates != null) {
             // Add remote ICE candidates from room.
             for (IceCandidate iceCandidate : params.iceCandidates) {
                 peerConnectionClient.addRemoteIceCandidate(iceCandidate);
             }
         }
     }
    

    }

    @OverRide
    public void onConnectedToRoom(final AppRTCClient.SignalingParameters params) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    onConnectedToRoomInternal(params);
    }
    });
    }

    @OverRide
    public void onRemoteDescription(final SessionDescription sdp) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received remote SDP for non-initilized peer connection.");
    return;
    }
    logAndToast("Received remote " + sdp.type + ", delay=" + delta + "ms");
    peerConnectionClient.setRemoteDescription(sdp);
    if (!signalingParameters.initiator) {
    logAndToast("Creating ANSWER...");
    // Create answer. Answer SDP will be sent to offering client in
    // PeerConnectionEvents.onLocalDescription event.
    peerConnectionClient.createAnswer();
    }
    }
    });
    }

    @OverRide
    public void onRemoteIceCandidate(final IceCandidate candidate) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received ICE candidate for a non-initialized peer connection.");
    return;
    }
    peerConnectionClient.addRemoteIceCandidate(candidate);
    }
    });
    }

    @OverRide
    public void onRemoteIceCandidatesRemoved(final IceCandidate[] candidates) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received ICE candidate removals for a non-initialized peer connection.");
    return;
    }
    peerConnectionClient.removeRemoteIceCandidates(candidates);
    }
    });
    }

    @OverRide
    public void onChannelClose() {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("Remote end hung up; dropping PeerConnection");
    disconnect();
    }
    });
    }

    @OverRide
    public void onChannelError(final String description) {
    reportError(description);
    }

    // -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
    // Send local peer connection SDP and ICE candidates to remote party.
    // All callbacks are invoked from peer connection client looper thread and
    // are routed to UI thread.
    @OverRide
    public void onLocalDescription(final SessionDescription sdp) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    logAndToast("Sending " + sdp.type + ", delay=" + delta + "ms");
    if (signalingParameters.initiator) {
    appRtcClient.sendOfferSdp(sdp);
    } else {
    appRtcClient.sendAnswerSdp(sdp);
    }
    }
    if (peerConnectionParameters.videoMaxBitrate > 0) {
    Log.d(TAG, "Set video maximum bitrate: " + peerConnectionParameters.videoMaxBitrate);
    peerConnectionClient.setVideoMaxBitrate(peerConnectionParameters.videoMaxBitrate);
    }
    }
    });
    }

    @OverRide
    public void onIceCandidate(final IceCandidate candidate) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    appRtcClient.sendLocalIceCandidate(candidate);
    }
    }
    });
    }

    @OverRide
    public void onIceCandidatesRemoved(final IceCandidate[] candidates) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    appRtcClient.sendLocalIceCandidateRemovals(candidates);
    }
    }
    });
    }

    @OverRide
    public void onIceConnected() {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("ICE connected, delay=" + delta + "ms");
    iceConnected = true;
    callConnected();
    }
    });
    }

    @OverRide
    public void onIceDisconnected() {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("ICE disconnected");
    iceConnected = false;
    disconnect();
    }
    });
    }

    @OverRide
    public void onPeerConnectionClosed() {
    }

    @OverRide
    public void onPeerConnectionStatsReady(final StatsReport[] reports) {
    }

    @OverRide
    public void onPeerConnectionError(final String description) {
    reportError(description);
    }

    // Activity interfaces
    @OverRide
    public void onStop() {
    super.onStop();
    activityRunning = false;
    if (peerConnectionClient != null) {
    peerConnectionClient.stopVideoSource();
    }
    }

    @OverRide
    public void onStart() {
    super.onStart();
    activityRunning = true;
    // Video is not paused for screencapture. See onPause.
    if (peerConnectionClient != null) {
    peerConnectionClient.startVideoSource();
    }
    }

    @OverRide
    protected void onDestroy() {
    Thread.setDefaultUncaughtExceptionHandler(null);
    disconnect();
    if (logToast != null) {
    logToast.cancel();
    }
    activityRunning = false;
    super.onDestroy();
    }

    private static class ProxyRenderer implements VideoRenderer.Callbacks {
    private VideoRenderer.Callbacks target;

     @Override
     synchronized public void renderFrame(VideoRenderer.I420Frame frame) {
         if (target == null) {
             Logging.d(TAG, "Dropping frame in proxy because target is null.");
             VideoRenderer.renderFrameDone(frame);
             return;
         }
    
         target.renderFrame(frame);
     }
    
     synchronized public void setTarget(VideoRenderer.Callbacks target) {
         this.target = target;
     }
    

    }

    private static class ProxyVideoSink implements VideoSink {
    private VideoSink target;

     @Override
     synchronized public void onFrame(VideoFrame frame) {
         if (target == null) {
             Logging.d(TAG, "Dropping frame in proxy because target is null.");
             return;
         }
    
         target.onFrame(frame);
     }
    
     synchronized public void setTarget(VideoSink target) {
         this.target = target;
     }
    

    }

}

@razakhan22
Copy link

Screenshot_2020-11-11-10-53-13-849_com skillatwill skillatwill

**I'm building video chat application using webrtc. when i started video call some error is coming. how to resolve that issue.

E/RoomRTCClient: Room connection error: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB

E/WSRTCClient: HTTP POST to https://appr.tc/join/E52U8KA error: Unacceptable certificate: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB**

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.UiThread;

import com.skillatwill.skillatwill.R;

import org.appspot.apprtc.AppRTCClient;
import org.appspot.apprtc.PeerConnectionClient;
import org.appspot.apprtc.WebSocketRTCClient;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
import org.webrtc.IceCandidate;
import org.webrtc.Logging;
import org.webrtc.RendererCommon.ScalingType;
import org.webrtc.SessionDescription;
import org.webrtc.StatsReport;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFrame;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSink;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

/**

  • Activity for peer connection call setup, call waiting

  • and call view.
    */
    public class CallActivity extends Activity implements AppRTCClient.SignalingEvents,
    PeerConnectionClient.PeerConnectionEvents {
    private static final String TAG = "CallActivity";
    private static final String APPRTC_URL = "https://appr.tc";
    private static final String UPPER_ALPHA_DIGITS = "ACEFGHJKLMNPQRUVWXY123456789";
    // Peer connection statistics callback period in ms.
    private static final int STAT_CALLBACK_PERIOD = 1000;
    private final ProxyRenderer remoteProxyRenderer = new ProxyRenderer();
    private final ProxyVideoSink localProxyVideoSink = new ProxyVideoSink();
    private final List<VideoRenderer.Callbacks> remoteRenderers = new ArrayList<>();
    private PeerConnectionClient peerConnectionClient = null;
    private AppRTCClient appRtcClient;
    private AppRTCClient.SignalingParameters signalingParameters;
    private SurfaceViewRenderer pipRenderer;
    private SurfaceViewRenderer fullscreenRenderer;
    private Toast logToast;
    private boolean activityRunning;
    private AppRTCClient.RoomConnectionParameters roomConnectionParameters;
    private PeerConnectionClient.PeerConnectionParameters peerConnectionParameters;
    private boolean iceConnected;
    private boolean isError;
    private long callStartedTimeMs = 0;
    private boolean micEnabled = true;
    private boolean isSwappedFeeds;
    // Control buttons for limited UI
    private ImageButton disconnectButton;
    private ImageButton cameraSwitchButton;
    private ImageButton toggleMuteButton;
    @OverRide
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     setContentView(R.layout.activity_call);
    
     iceConnected = false;
     signalingParameters = null;
    
     // Create UI controls.
     pipRenderer = findViewById(R.id.pip_video_view);
     fullscreenRenderer = findViewById(R.id.fullscreen_video_view);
    
     disconnectButton = findViewById(R.id.button_call_disconnect);
     cameraSwitchButton = findViewById(R.id.button_call_switch_camera);
     toggleMuteButton = findViewById(R.id.button_call_toggle_mic);
    
     // Add buttons click events.
     disconnectButton.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
             onCallHangUp();
         }
     });
    
     cameraSwitchButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             onCameraSwitch();
         }
     });
    
     toggleMuteButton.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             boolean enabled = onToggleMic();
             toggleMuteButton.setAlpha(enabled ? 1.0f : 0.3f);
         }
     });
    
     // Swap feeds on pip view click.
     pipRenderer.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
             setSwappedFeeds(!isSwappedFeeds);
         }
     });
    
     remoteRenderers.add(remoteProxyRenderer);
    
     // Create peer connection client.
     peerConnectionClient = new PeerConnectionClient();
    
     // Create video renderers.
     pipRenderer.init(peerConnectionClient.getRenderContext(), null);
     pipRenderer.setScalingType(ScalingType.SCALE_ASPECT_FIT);
    
     fullscreenRenderer.init(peerConnectionClient.getRenderContext(), null);
     fullscreenRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL);
    
     pipRenderer.setZOrderMediaOverlay(true);
     pipRenderer.setEnableHardwareScaler(true /* enabled */);
     fullscreenRenderer.setEnableHardwareScaler(true /* enabled */);
     // Start with local feed in fullscreen and swap it to the pip when the call is connected.
     setSwappedFeeds(true /* isSwappedFeeds */);
    
     // Generate a random room ID with 7 uppercase letters and digits
     String randomRoomID = randomString(7, UPPER_ALPHA_DIGITS);
     // Show the random room ID so that another client can join from https://appr.tc
     TextView roomIdTextView = findViewById(R.id.roomID);
    
    
    
     roomIdTextView.setText(getString(R.string.room_id_caption) + randomRoomID);
    
     Log.d(TAG, getString(R.string.room_id_caption) + randomRoomID);
    
     // Connect video call to the random room
     connectVideoCall(randomRoomID);
    

    }
    // Create a random string
    private String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
    int randomInt = new SecureRandom().nextInt(characterSet.length());
    sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
    }
    // Join video call with randomly generated roomId
    private void connectVideoCall(String roomId) {
    Uri roomUri = Uri.parse(APPRTC_URL);

     int videoWidth = 0;
     int videoHeight = 0;
    
     peerConnectionParameters =
             new PeerConnectionClient.PeerConnectionParameters(true,
                     false,
                     false,
                     videoWidth,
                     videoHeight,
                     0,
                     Integer.parseInt(getString(R.string.pref_maxvideobitratevalue_default)),
                     getString(R.string.pref_videocodec_default),
                     true,
                     false,
                     Integer.parseInt(getString(R.string.pref_startaudiobitratevalue_default)),
                     getString(R.string.pref_audiocodec_default),
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     false,
                     null);
    
     // Create connection client. Use the standard WebSocketRTCClient.
     // DirectRTCClient could be used for point-to-point connection
     appRtcClient = new WebSocketRTCClient(this);
     // Create connection parameters.
     roomConnectionParameters =
             new AppRTCClient.RoomConnectionParameters(
                     roomUri.toString(),
                     roomId,
                     false,
                     null);
    
     peerConnectionClient.createPeerConnectionFactory(
             getApplicationContext(), peerConnectionParameters, CallActivity.this);
    
     startCall();
    

    }
    public void onCallHangUp() {
    disconnect();
    }
    public void onCameraSwitch() {
    if (peerConnectionClient != null) {
    peerConnectionClient.switchCamera();
    }
    }
    public boolean onToggleMic() {
    if (peerConnectionClient != null) {
    micEnabled = !micEnabled;
    peerConnectionClient.setAudioEnabled(micEnabled);
    }
    return micEnabled;
    }
    private void startCall() {
    if (appRtcClient == null) {
    Log.e(TAG, "AppRTC client is not allocated for a call.");
    return;
    }
    callStartedTimeMs = System.currentTimeMillis();

     // Start room connection.
     logAndToast(getString(R.string.connecting_to, roomConnectionParameters.roomUrl));
     appRtcClient.connectToRoom(roomConnectionParameters);
    

    }
    @UiThread
    private void callConnected() {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    Log.i(TAG, "Call connected: delay=" + delta + "ms");
    if (peerConnectionClient == null || isError) {
    Log.w(TAG, "Call is connected in closed or error state");
    return;
    }
    // Enable statistics callback.
    peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
    setSwappedFeeds(false /* isSwappedFeeds */);
    }
    // Disconnect from remote resources, dispose of local resources, and exit.
    private void disconnect() {
    activityRunning = false;
    remoteProxyRenderer.setTarget(null);
    localProxyVideoSink.setTarget(null);
    if (appRtcClient != null) {
    appRtcClient.disconnectFromRoom();
    appRtcClient = null;
    }
    if (pipRenderer != null) {
    pipRenderer.release();
    pipRenderer = null;
    }
    if (fullscreenRenderer != null) {
    fullscreenRenderer.release();
    fullscreenRenderer = null;
    }
    if (peerConnectionClient != null) {
    peerConnectionClient.close();
    peerConnectionClient = null;
    }
    if (iceConnected && !isError) {
    setResult(RESULT_OK);
    } else {
    setResult(RESULT_CANCELED);
    }
    finish();
    }
    private void disconnectWithErrorMessage(final String errorMessage) {
    if (!activityRunning) {
    Log.e(TAG, "Critical error: " + errorMessage);
    disconnect();
    } else {
    new AlertDialog.Builder(this)
    .setTitle(getText(R.string.channel_error_title))
    .setMessage(errorMessage)
    .setCancelable(false)
    .setNeutralButton(R.string.ok,
    new DialogInterface.OnClickListener() {
    @OverRide
    public void onClick(DialogInterface dialog, int id) {
    dialog.cancel();
    disconnect();
    }
    })
    .create()
    .show();
    }
    }
    // Log |msg| and Toast about it.
    private void logAndToast(String msg) {
    Log.d(TAG, msg);
    if (logToast != null) {
    logToast.cancel();
    }
    logToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
    logToast.show();
    }
    private void reportError(final String description) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (!isError) {
    isError = true;
    disconnectWithErrorMessage(description);
    }
    }
    });
    }
    // Create VideoCapturer
    private VideoCapturer createVideoCapturer() {
    final VideoCapturer videoCapturer;
    Logging.d(TAG, "Creating capturer using camera2 API.");
    videoCapturer = createCameraCapturer(new Camera2Enumerator(this));
    if (videoCapturer == null) {
    reportError("Failed to open camera");
    return null;
    }
    return videoCapturer;
    }
    // Create VideoCapturer from camera
    private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
    final String[] deviceNames = enumerator.getDeviceNames();

     // First, try to find front facing camera
     Logging.d(TAG, "Looking for front facing cameras.");
     for (String deviceName : deviceNames) {
         if (enumerator.isFrontFacing(deviceName)) {
             Logging.d(TAG, "Creating front facing camera capturer.");
             VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
    
             if (videoCapturer != null) {
                 return videoCapturer;
             }
         }
     }
    
     // Front facing camera not found, try something else
     Logging.d(TAG, "Looking for other cameras.");
     for (String deviceName : deviceNames) {
         if (!enumerator.isFrontFacing(deviceName)) {
             Logging.d(TAG, "Creating other camera capturer.");
             VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
    
             if (videoCapturer != null) {
                 return videoCapturer;
             }
         }
     }
    
     return null;
    

    }
    private void setSwappedFeeds(boolean isSwappedFeeds) {
    Logging.d(TAG, "setSwappedFeeds: " + isSwappedFeeds);
    this.isSwappedFeeds = isSwappedFeeds;
    localProxyVideoSink.setTarget(isSwappedFeeds ? fullscreenRenderer : pipRenderer);
    remoteProxyRenderer.setTarget(isSwappedFeeds ? pipRenderer : fullscreenRenderer);
    fullscreenRenderer.setMirror(isSwappedFeeds);
    pipRenderer.setMirror(!isSwappedFeeds);
    }
    // -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
    // All callbacks are invoked from websocket signaling looper thread and
    // are routed to UI thread.
    private void onConnectedToRoomInternal(final AppRTCClient.SignalingParameters params) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;

     signalingParameters = params;
     logAndToast("Creating peer connection, delay=" + delta + "ms");
     VideoCapturer videoCapturer = null;
     if (peerConnectionParameters.videoCallEnabled) {
         videoCapturer = createVideoCapturer();
     }
     peerConnectionClient.createPeerConnection(
             localProxyVideoSink, remoteRenderers, videoCapturer, signalingParameters);
    
     if (signalingParameters.initiator) {
         logAndToast("Creating OFFER...");
         // Create offer. Offer SDP will be sent to answering client in
         // PeerConnectionEvents.onLocalDescription event.
         peerConnectionClient.createOffer();
     } else {
         if (params.offerSdp != null) {
             peerConnectionClient.setRemoteDescription(params.offerSdp);
             logAndToast("Creating ANSWER...");
             // Create answer. Answer SDP will be sent to offering client in
             // PeerConnectionEvents.onLocalDescription event.
             peerConnectionClient.createAnswer();
         }
         if (params.iceCandidates != null) {
             // Add remote ICE candidates from room.
             for (IceCandidate iceCandidate : params.iceCandidates) {
                 peerConnectionClient.addRemoteIceCandidate(iceCandidate);
             }
         }
     }
    

    }
    @OverRide
    public void onConnectedToRoom(final AppRTCClient.SignalingParameters params) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    onConnectedToRoomInternal(params);
    }
    });
    }
    @OverRide
    public void onRemoteDescription(final SessionDescription sdp) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received remote SDP for non-initilized peer connection.");
    return;
    }
    logAndToast("Received remote " + sdp.type + ", delay=" + delta + "ms");
    peerConnectionClient.setRemoteDescription(sdp);
    if (!signalingParameters.initiator) {
    logAndToast("Creating ANSWER...");
    // Create answer. Answer SDP will be sent to offering client in
    // PeerConnectionEvents.onLocalDescription event.
    peerConnectionClient.createAnswer();
    }
    }
    });
    }
    @OverRide
    public void onRemoteIceCandidate(final IceCandidate candidate) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received ICE candidate for a non-initialized peer connection.");
    return;
    }
    peerConnectionClient.addRemoteIceCandidate(candidate);
    }
    });
    }
    @OverRide
    public void onRemoteIceCandidatesRemoved(final IceCandidate[] candidates) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (peerConnectionClient == null) {
    Log.e(TAG, "Received ICE candidate removals for a non-initialized peer connection.");
    return;
    }
    peerConnectionClient.removeRemoteIceCandidates(candidates);
    }
    });
    }
    @OverRide
    public void onChannelClose() {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("Remote end hung up; dropping PeerConnection");
    disconnect();
    }
    });
    }
    @OverRide
    public void onChannelError(final String description) {
    reportError(description);
    }
    // -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
    // Send local peer connection SDP and ICE candidates to remote party.
    // All callbacks are invoked from peer connection client looper thread and
    // are routed to UI thread.
    @OverRide
    public void onLocalDescription(final SessionDescription sdp) {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    logAndToast("Sending " + sdp.type + ", delay=" + delta + "ms");
    if (signalingParameters.initiator) {
    appRtcClient.sendOfferSdp(sdp);
    } else {
    appRtcClient.sendAnswerSdp(sdp);
    }
    }
    if (peerConnectionParameters.videoMaxBitrate > 0) {
    Log.d(TAG, "Set video maximum bitrate: " + peerConnectionParameters.videoMaxBitrate);
    peerConnectionClient.setVideoMaxBitrate(peerConnectionParameters.videoMaxBitrate);
    }
    }
    });
    }
    @OverRide
    public void onIceCandidate(final IceCandidate candidate) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    appRtcClient.sendLocalIceCandidate(candidate);
    }
    }
    });
    }
    @OverRide
    public void onIceCandidatesRemoved(final IceCandidate[] candidates) {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    if (appRtcClient != null) {
    appRtcClient.sendLocalIceCandidateRemovals(candidates);
    }
    }
    });
    }
    @OverRide
    public void onIceConnected() {
    final long delta = System.currentTimeMillis() - callStartedTimeMs;
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("ICE connected, delay=" + delta + "ms");
    iceConnected = true;
    callConnected();
    }
    });
    }
    @OverRide
    public void onIceDisconnected() {
    runOnUiThread(new Runnable() {
    @OverRide
    public void run() {
    logAndToast("ICE disconnected");
    iceConnected = false;
    disconnect();
    }
    });
    }
    @OverRide
    public void onPeerConnectionClosed() {
    }
    @OverRide
    public void onPeerConnectionStatsReady(final StatsReport[] reports) {
    }
    @OverRide
    public void onPeerConnectionError(final String description) {
    reportError(description);
    }
    // Activity interfaces
    @OverRide
    public void onStop() {
    super.onStop();
    activityRunning = false;
    if (peerConnectionClient != null) {
    peerConnectionClient.stopVideoSource();
    }
    }
    @OverRide
    public void onStart() {
    super.onStart();
    activityRunning = true;
    // Video is not paused for screencapture. See onPause.
    if (peerConnectionClient != null) {
    peerConnectionClient.startVideoSource();
    }
    }
    @OverRide
    protected void onDestroy() {
    Thread.setDefaultUncaughtExceptionHandler(null);
    disconnect();
    if (logToast != null) {
    logToast.cancel();
    }
    activityRunning = false;
    super.onDestroy();
    }
    private static class ProxyRenderer implements VideoRenderer.Callbacks {
    private VideoRenderer.Callbacks target;

     @Override
     synchronized public void renderFrame(VideoRenderer.I420Frame frame) {
         if (target == null) {
             Logging.d(TAG, "Dropping frame in proxy because target is null.");
             VideoRenderer.renderFrameDone(frame);
             return;
         }
    
         target.renderFrame(frame);
     }
    
     synchronized public void setTarget(VideoRenderer.Callbacks target) {
         this.target = target;
     }
    

    }
    private static class ProxyVideoSink implements VideoSink {
    private VideoSink target;

     @Override
     synchronized public void onFrame(VideoFrame frame) {
         if (target == null) {
             Logging.d(TAG, "Dropping frame in proxy because target is null.");
             return;
         }
    
         target.onFrame(frame);
     }
    
     synchronized public void setTarget(VideoSink target) {
         this.target = target;
     }
    

    }

}

Bro this error is happening becoz of SSL certificate is expired of this servers website

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants