public IActionResult OnGetCalls() { _logger.Info("Getting calls"); if (_botService.CallHandlers.IsEmpty) { return(StatusCode(203)); } var calls = new List <Dictionary <string, string> >(); foreach (var callHandler in _botService.CallHandlers.Values) { var call = callHandler.Call; var callPath = "/" + HttpRouteConstants.CallRoute.Replace("{callLegId}", call.Id); var callUri = new Uri(_settings.CallControlBaseUrl, callPath).AbsoluteUri; var values = new Dictionary <string, string> { { "legId", call.Id }, { "scenarioId", call.ScenarioId.ToString() }, { "call", callUri }, { "logs", callUri.Replace("/calls/", "/logs/") }, }; calls.Add(values); } return(Ok(calls)); }
public HttpResponseMessage OnGetCalls() { _logger.Info("Getting calls"); _eventPublisher.Publish("GetCalls", "Getting calls"); if (_botService.CallHandlers.IsEmpty) { return(this.Request.CreateResponse(HttpStatusCode.NoContent)); } var calls = new List <Dictionary <string, string> >(); foreach (var callHandler in _botService.CallHandlers.Values) { var call = callHandler.Call; var callPath = "/" + HttpRouteConstants.CallRoute.Replace("{callLegId}", call.Id); var callUri = new Uri(_settings.CallControlBaseUrl, callPath).AbsoluteUri; var values = new Dictionary <string, string> { { "legId", call.Id }, { "scenarioId", call.ScenarioId.ToString() }, { "call", callUri }, { "logs", callUri.Replace("/calls/", "/logs/") }, }; calls.Add(values); } var serializer = new CommsSerializer(pretty: true); var json = serializer.SerializeObject(calls); var response = this.Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(json, Encoding.UTF8, "application/json"); return(response); }
public async Task <IActionResult> OnIncomingRequestAsync() { var log = $"Received HTTP {this.Request.Method}, {this.Request.Path.Value}"; _logger.Info(log); var response = await _botService.Client.ProcessNotificationAsync(ConvertHttpRequestToHttpRequestMessage(this.Request)).ConfigureAwait(false); var content = response.Content == null ? null : await response.Content?.ReadAsStringAsync(); return(Ok(content)); }
/// <summary> /// Joins the call asynchronously. /// </summary> /// <param name="joinCallBody">The join call body.</param> /// <param name="incidentId">Incident Id.</param> /// <returns>The <see cref="ICall"/> that was requested to join.</returns> public async Task <ICall> JoinCallAsync(JoinCallRequestData joinCallBody, string incidentId = "") { // A tracking id for logging purposes. Helps identify this call in logs. var scenarioId = string.IsNullOrEmpty(joinCallBody.ScenarioId) ? Guid.NewGuid() : new Guid(joinCallBody.ScenarioId); MeetingInfo meetingInfo; ChatInfo chatInfo; if (!string.IsNullOrWhiteSpace(joinCallBody.VideoTeleconferenceId)) { // Meeting id is a cloud-video-interop numeric meeting id. var onlineMeeting = await OnlineMeetings .GetOnlineMeetingAsync(joinCallBody.TenantId, joinCallBody.VideoTeleconferenceId, scenarioId) .ConfigureAwait(false); meetingInfo = new OrganizerMeetingInfo { Organizer = onlineMeeting.Participants.Organizer.Identity, }; chatInfo = onlineMeeting.ChatInfo; } else { (chatInfo, meetingInfo) = JoinInfo.ParseJoinURL(joinCallBody.JoinUrl); } var tenantId = joinCallBody.TenantId ?? (meetingInfo as OrganizerMeetingInfo)?.Organizer.GetPrimaryIdentity()?.GetTenantId(); var mediaToPrefetch = new List <MediaInfo>(); foreach (var m in MediaMap) { mediaToPrefetch.Add(m.Value.MediaInfo); } var joinParams = new JoinMeetingParameters(chatInfo, meetingInfo, new[] { Modality.Audio }, mediaToPrefetch) { TenantId = tenantId, }; var statefulCall = await Client.Calls().AddAsync(joinParams, scenarioId).ConfigureAwait(false); AddCallToHandlers(statefulCall, new IncidentCallContext(IncidentCallType.BotMeeting, incidentId)); graphLogger.Info($"Join Call complete: {statefulCall.Id}"); return(statefulCall); }
public async Task <HttpResponseMessage> OnIncomingRequestAsync() { var log = $"Received HTTP {this.Request.Method}, {this.Request.RequestUri}"; _logger.Info(log); _eventPublisher.Publish($"IncomingHTTP{this.Request.Method}", $"{this.Request.RequestUri}"); // Instead of passing incoming notification to SDK, let's process it ourselves // so we can handle any policy evaluations. var response = await ProcessNotificationAsync(_botService.Client, this.Request).ConfigureAwait(false); // Enforce the connection close to ensure that requests are evenly load balanced so // calls do no stick to one instance of the worker role. response.Headers.ConnectionClose = true; return(response); }
/// <summary> /// Starts the server. /// </summary> public void StartServer() { try { _botService.Initialize(); var callStartOptions = new StartOptions(); foreach (var url in ((AzureSettings)_settings).CallControlListeningUrls) { callStartOptions.Urls.Add(url); _logger.Info("Listening on: {url}", url); } _callHttpServer = WebApp.Start( callStartOptions, (appBuilder) => { var startup = new HttpConfigurationInitializer(); startup.ConfigureSettings(appBuilder, _logger); }); } catch (Exception e) { _logger.Error(e, "Unhandled exception in StartServer()"); throw; } }
/// <summary> /// Helper function to create the audio buffers from file. /// Please make sure the audio file provided is PCM16Khz and the fileSizeInSec is the correct length. /// </summary> /// <param name="currentTick">The current clock tick.</param> /// <param name="replayed">Whether it's replayed.</param> /// <param name="logger">Graph logger.</param> /// <returns>The newly created list of <see cref="AudioMediaBuffer"/>.</returns> public static List <AudioMediaBuffer> CreateAudioMediaBuffers(long currentTick, bool replayed, IGraphLogger logger) { var audioMediaBuffers = new List <AudioMediaBuffer>(); var referenceTime = currentTick; // packet size of 20 ms var numberOfTicksInOneAudioBuffers = 20 * 10000; if (replayed) { referenceTime += numberOfTicksInOneAudioBuffers; } using (FileStream fs = File.Open(Service.Instance.Configuration.AudioFileLocation, FileMode.Open)) { byte[] bytesToRead = new byte[640]; // skipping the wav headers fs.Seek(44, SeekOrigin.Begin); while (fs.Read(bytesToRead, 0, bytesToRead.Length) >= 640) { // here we want to create buffers of 20MS with PCM 16Khz IntPtr unmanagedBuffer = Marshal.AllocHGlobal(640); Marshal.Copy(bytesToRead, 0, unmanagedBuffer, 640); var audioBuffer = new AudioSendBuffer(unmanagedBuffer, 640, AudioFormat.Pcm16K, referenceTime); audioMediaBuffers.Add(audioBuffer); referenceTime += numberOfTicksInOneAudioBuffers; } } logger.Info($"created {audioMediaBuffers.Count} AudioMediaBuffers"); return(audioMediaBuffers); }
/// <summary> /// Chunks the process. /// </summary> async Task _chunkProcess() { try { var finalData = await _currentAudioProcessor.Finalise(); _logger.Info($"Recording saved to: {finalData}"); } catch (Exception ex) { _logger.Error(ex, "Caught exception while processing chunck."); } }
/// <summary> /// Creates the video buffers from the provided h264 files. /// </summary> /// <param name="currentTick">The number of ticks that represent the current date and time.</param> /// <param name="videoFormats">The encoded video source formats.</param> /// <param name="replayed">If the video frame is being replayed.</param> /// <param name="logger">Graph logger.</param> /// <returns>The newly created list of <see cref="VideoMediaBuffer"/>.</returns> public static List <VideoMediaBuffer> CreateVideoMediaBuffers( long currentTick, List <VideoFormat> videoFormats, bool replayed, IGraphLogger logger) { List <VideoMediaBuffer> videoMediaBuffers = new List <VideoMediaBuffer>(); try { foreach (var videoFormat in videoFormats) { if (H264Frames.TryGetValue(videoFormat.GetId(), out List <H264Frame> h264Frames)) { // create the videoBuffers var packetSizeInMs = (long)((MsInOneSec / videoFormat.FrameRate) * TicksInOneMs); var referenceTime = currentTick; if (replayed) { referenceTime += packetSizeInMs; } foreach (var h264Frame in h264Frames) { var frameSize = h264Frame.Size; byte[] buffer = new byte[frameSize]; Marshal.Copy(h264Frame.Data, buffer, 0, (int)frameSize); videoMediaBuffers.Add(new VideoSendBuffer(buffer, (uint)buffer.Length, videoFormat, referenceTime)); referenceTime += packetSizeInMs; } } else { logger.Error($"h264FileReader not found for the videoFromat {videoFormat}"); } } logger.Info($"created {videoMediaBuffers.Count} VideoMediaBuffers"); return(videoMediaBuffers); } catch (Exception ex) { logger.Error(ex, $"Failed to create the videoMediaBuffers with exception"); } return(videoMediaBuffers); }
/// <summary> /// Transform NV12 to bmp image so we can view how is it looks like. Note it's not NV12 to RBG conversion. /// </summary> /// <param name="data">NV12 sample data.</param> /// <param name="width">Image width.</param> /// <param name="height">Image height.</param> /// <param name="logger">Log instance.</param> /// <returns>The <see cref="Bitmap"/>.</returns> public static Bitmap TransformNv12ToBmpFaster(byte[] data, int width, int height, IGraphLogger logger) { Stopwatch watch = new Stopwatch(); watch.Start(); var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb); var bmpData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); var uvStart = width * height; for (var y = 0; y < height; y++) { var pos = y * width; var posInBmp = y * bmpData.Stride; for (var x = 0; x < width; x++) { var vIndex = uvStart + ((y >> 1) * width) + (x & ~1); //// https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx //// https://en.wikipedia.org/wiki/YUV var c = data[pos] - 16; var d = data[vIndex] - 128; var e = data[vIndex + 1] - 128; c = c < 0 ? 0 : c; var r = ((298 * c) + (409 * e) + 128) >> 8; var g = ((298 * c) - (100 * d) - (208 * e) + 128) >> 8; var b = ((298 * c) + (516 * d) + 128) >> 8; r = r.Clamp(0, 255); g = g.Clamp(0, 255); b = b.Clamp(0, 255); Marshal.WriteInt32(bmpData.Scan0, posInBmp + (x << 2), (b << 0) | (g << 8) | (r << 16) | (0xFF << 24)); pos++; } } bmp.UnlockBits(bmpData); watch.Stop(); logger.Info($"Took {watch.ElapsedMilliseconds} ms to lock and unlock"); return(bmp); }
public async Task <IActionResult> OnIncomingRequestAsync() { var requestMessage = Request.HttpContext.GetHttpRequestMessage(); var requestUri = requestMessage.RequestUri; // Process the incoming request for current web instance. bot.AddCallbackLog($"Process incoming request {requestUri}"); var token = requestMessage.Headers?.Authorization?.Parameter; bot.AddCallbackLog($"Token: {token ?? "null"}"); graphLogger.Info($"Received HTTP {Request.Method}, {requestUri}"); // Pass the incoming message to the sdk. The sdk takes care of what to do with it. var response = await bot.Client.ProcessNotificationAsync(requestMessage).ConfigureAwait(false); // Convert the status code, content of HttpResponseMessage to IActionResult, // and copy the headers from response to HttpContext.Response.Headers. return(await this.GetActionResultAsync(response).ConfigureAwait(false)); }