/// <summary> /// Notify application upon incoming DTMF digits. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void _call_OnDtmfDigit(object sender, Nequeo.Net.PjSip.OnDtmfDigitParam e) { Param.OnDtmfDigitParam param = new OnDtmfDigitParam(); param.Digit = e.Digit; Nequeo.Net.PjSip.CallInfo ci = e.Info; if (ci != null) { param.From = ci.RemoteUri; param.FromContact = ci.RemoteContact; } try { // Handle the event. OnDtmfDigit?.Invoke(this, param); } catch { } }
/// <summary> /// Notify application when call state has changed. /// Application may then query the call info to get the /// detail call states by calling getInfo() function. /// </summary> /// <param name="sender">The current sender.</param> /// <param name="e">The event parameter.</param> private void _call_OnCallState(object sender, OnCallStateParam e) { Nequeo.Net.PjSip.CallInfo ci = e.Info; if (ci != null) { _info = null; try { // Create the call info. _info = new CallInfoParam(); _info.CallID = ci.Id; _info.Guid = _guid; _info.Contact = ci.RemoteContact; _info.FromTo = ci.RemoteUri; _info.Date = DateTime.Now; _info.ConnectDuration = new TimeSpan(0, 0, 0, ci.ConnectDuration.Seconds, ci.ConnectDuration.Milliseconds); _info.TotalDuration = new TimeSpan(0, 0, 0, ci.TotalDuration.Seconds, ci.TotalDuration.Milliseconds); } catch { _info = null; } Param.CallStateParam callState = new CallStateParam(); callState.CallID = ci.Id; callState.State = ci.State; callState.CallInfo = _info; try { // Handle the event. OnCallState?.Invoke(this, callState); // Set the contact name. _info.ContactName = callState.ContactName; } catch { } // If call is disconnected. if ((ci.State == InviteSessionState.PJSIP_INV_STATE_DISCONNECTED) || (ci.State == InviteSessionState.PJSIP_INV_STATE_NULL)) { // If current call. if (e.CurrentCall != null) { try { // Cleanup the call. e.CurrentCall.Dispose(); e.CurrentCall = null; } catch { } } // If recoder. if (_recorder != null) { try { // Stop the recorder. AudioMedia audioMedia = _mediaManager.GetCaptureDeviceMedia(); _recorder.Stop(audioMedia); } catch { } try { // Cleanup the recoder. _recorder.Dispose(); _recorder = null; } catch { } } // If auto answer recoder. if (_recorderAutoAnswer != null) { try { // Cleanup the recoder. _recorderAutoAnswer.Dispose(); _recorderAutoAnswer = null; } catch { } } // If sound player. if (_player != null) { try { // Cleanup the recoder. _player.Dispose(); _player = null; } catch { } } // If video window. if (_videoWindow != null) { try { _hasVideo = false; // Cleanup the video window. _videoWindow.Dispose(); _videoWindow = null; } catch { } } // Cleanup the audio media. if (_audioMedias != null) { _audioMedias.Clear(); _audioMedias = null; } } // If call is disconnected. if ((ci.State == InviteSessionState.PJSIP_INV_STATE_DISCONNECTED) || (ci.State == InviteSessionState.PJSIP_INV_STATE_NULL)) { try { // Handle the event. OnCallDisconnected?.Invoke(this, _info); } catch { } } } }
/// <summary> /// Notify application when media state in the call has changed. /// Normal application would need to implement this callback, e.g. /// to connect the call's media to sound device. When ICE is used, /// this callback will also be called to report ICE negotiation failure. /// </summary> /// <param name="sender">The current sender.</param> /// <param name="e">The event parameter.</param> private void _call_OnCallMediaState(object sender, OnCallMediaStateParam e) { Nequeo.Net.PjSip.CallInfo ci = e.Info; if (ci != null) { // For each media. for (int i = 0; i < ci.Media.Length; i++) { bool recoderSet = false; // If objects exist. if (ci.Media != null && ci.Media[i] != null && e.CurrentCall != null) { // Create the call media param. CallMediaStateParam mediaState = new CallMediaStateParam(); mediaState.Suspend = false; mediaState.CallID = ci.Id; mediaState.CallOnHold = (ci.Media[i].Status == CallMediaStatus.PJSUA_CALL_MEDIA_LOCAL_HOLD ? true : false); mediaState.MediaType = ci.Media[i].Type; // If video type. if (ci.Media[i].Type == Nequeo.Net.PjSip.MediaType.PJMEDIA_TYPE_VIDEO) { _hasVideo = true; _videoWindow = ci.Media[i].VideoWindowEx; mediaState.HasVideo = _hasVideo; _isVideoValid = (ci.Media[i].Direction == MediaDirection.PJMEDIA_DIR_NONE ? false : true); mediaState.IsVideoValid = _isVideoValid; } else { _hasVideo = false; _isVideoValid = false; _videoWindow = null; mediaState.HasVideo = _hasVideo; mediaState.IsVideoValid = _isVideoValid; } // Handle the event. OnCallMediaState?.Invoke(this, mediaState); // If audio type. if ((ci.Media[i].Type == Nequeo.Net.PjSip.MediaType.PJMEDIA_TYPE_AUDIO) && (e.CurrentCall.GetMedia((uint)i) != null)) { // Get the audio media. AudioMedia audioMedia = (AudioMedia)e.CurrentCall.GetMedia((uint)i); _audioMedias.Add(audioMedia); // If not suspend, normal operations. if (!mediaState.Suspend) { // Transmitting. _isTransmitting = true; // Connect the call audio media to sound device. audioMedia.StartTransmit(_mediaManager.GetPlaybackDeviceMedia()); _mediaManager.GetCaptureDeviceMedia().StartTransmit(audioMedia); // If recording. if (!recoderSet && !String.IsNullOrEmpty(_recordFilename)) { // Get the capture audio device. AudioMedia audioMediaRecord = _mediaManager.GetCaptureDeviceMedia(); try { // Create the recorder. _recorder = new AudioMediaRecorder(); _recorder.CreateRecorder(_recordFilename, 0, 0, 0); _recorder.StartRecordingConversation(audioMediaRecord, new AudioMedia[] { audioMedia }); } catch { } // Set one recorder. recoderSet = true; } } } // If video type. if (ci.Media[i].Type == Nequeo.Net.PjSip.MediaType.PJMEDIA_TYPE_VIDEO) { } } } } }