private void RemoteVideoStreamAdded(ACSRemoteVideoStream remoteVideoStream)
 {
     if (!remoteVideoStream.IsAvailable ||
         _remoteVideoStreams.Any(s => s.Id == remoteVideoStream.Id))
     {
         return;
     }
     
     _remoteVideoStreams.Add(remoteVideoStream);
     Device.BeginInvokeOnMainThread(() =>
     {
         var renderer = new ACSVideoStreamRenderer(remoteVideoStream, out var rendererError);
         ThrowIfError(rendererError);
         var renderingOptions = new ACSRenderingOptions(ACSScalingMode.Crop);
         var nativeView = renderer.CreateViewWithOptions(renderingOptions, out var createViewError);
         ThrowIfError(createViewError);
         var formsView = nativeView.ToView();
         RemoteVideoAdded?.Invoke(this, formsView);
     });
 }
        public async Task JoinGroup(Guid groupID)
        {
            var camera = _deviceManager
                .Cameras.First(c => c.CameraFacing == ACSCameraFacing.Front);
            _localVideoStream = new ACSLocalVideoStream(camera);
            _localVideoStreamRenderer = new ACSVideoStreamRenderer(_localVideoStream, out var rendererError);
            ThrowIfError(rendererError);
            var renderingOptions = new ACSRenderingOptions(ACSScalingMode.Crop);
            var nativeView = _localVideoStreamRenderer.CreateViewWithOptions(renderingOptions, out var viewError);
            ThrowIfError(viewError);
            var formsView = nativeView.ToView();

            LocalVideoAdded?.Invoke(this, formsView);

            var groupCallLocator = new ACSGroupCallLocator(new NSUuid(groupID.ToString()));
            var callOptions = new ACSJoinCallOptions
            {
                AudioOptions = new ACSAudioOptions(),
                VideoOptions = new ACSVideoOptions(_localVideoStream)
            };
            //callOptions.AudioOptions.Muted = true;
            _call = _callAgent.JoinWithMeetingLocator(groupCallLocator, callOptions);
            // Respond to changes
            _call.Delegate = new CallDelegate(_videoCallbackManager);
            // Setup initial streams. This is clumsy and probably an API flaw...
            // IMHO delegate should be called after setting it on existing state...
            foreach (var remoteParticipant in _call.RemoteParticipants)
            {
                remoteParticipant.Delegate = new RemoteParticipantDelegate(_videoCallbackManager);
                foreach (var remoteVideoStream in remoteParticipant.VideoStreams)
                {
                    RemoteVideoStreamAdded(remoteVideoStream);
                }
            }

            _call.StartVideo(_localVideoStream, OnVideoStarted);
        }