/// <summary> /// Processes this instance. /// </summary> private async Task _process() { _currentAudioProcessor = new AudioProcessor(_settings); if (_settings.CaptureEvents && !_isDraining && _capture == null) { _capture = new CaptureEvents(Path.Combine(Path.GetTempPath(), BotConstants.DefaultOutputFolder, _settings.EventsFolder, _mediaId, "media")); } try { while (await _buffer.OutputAvailableAsync(_tokenSource.Token).ConfigureAwait(false)) { SerializableAudioMediaBuffer data = await _buffer.ReceiveAsync(_tokenSource.Token).ConfigureAwait(false); if (_settings.CaptureEvents) { await _capture?.Append(data); } await _currentAudioProcessor.Append(data); _tokenSource.Token.ThrowIfCancellationRequested(); } } catch (TaskCanceledException ex) { _logger.Error(ex, "The queue processing task has been cancelled."); } catch (ObjectDisposedException ex) { _logger.Error(ex, "The queue processing task object has been disposed."); } catch (Exception ex) { // Catch all other exceptions and log _logger.Error(ex, "Caught Exception"); // Continue processing elements in the queue await _process().ConfigureAwait(false); } //send final segment as a last precation in case the loop did not process it if (_currentAudioProcessor != null) { await _chunkProcess(); } if (_settings.CaptureEvents) { await _capture?.Finalise(); } _isDraining = false; }
/// <summary> /// Event fired when the call has been updated. /// </summary> /// <param name="sender">The call.</param> /// <param name="e">The event args containing call changes.</param> private async void CallOnUpdated(ICall sender, ResourceEventArgs <Call> e) { GraphLogger.Info($"Call status updated to {e.NewResource.State} - {e.NewResource.ResultInfo?.Message}"); // Event - Recording update e.g established/updated/start/ended _eventPublisher.Publish($"Call{e.NewResource.State}", $"Call.ID {Call.Id} Sender.Id {sender.Id} status updated to {e.NewResource.State} - {e.NewResource.ResultInfo?.Message}"); if (e.OldResource.State != e.NewResource.State && e.NewResource.State == CallState.Established) { if (!_isDisposed) { // Call is established. We should start receiving Audio, we can inform clients that we have started recording. OnRecordingStatusFlip(sender, null); } } if ((e.OldResource.State == CallState.Established) && (e.NewResource.State == CallState.Terminated)) { if (BotMediaStream != null) { var aQoE = BotMediaStream.GetAudioQualityOfExperienceData(); if (aQoE != null) { if (_settings.CaptureEvents) { await _capture?.Append(aQoE); } } await BotMediaStream.StopMedia(); } if (_settings.CaptureEvents) { await _capture?.Finalise(); } } }