示例#1
0
        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));
        }
示例#4
0
        /// <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;
            }
        }
示例#7
0
        /// <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.");
            }
        }
示例#9
0
        /// <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);
        }
示例#10
0
        /// <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);
        }
示例#11
0
        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));
        }