/// <summary>
        /// Generates And Submit Frames
        /// </summary>
        /// <param name="assetInfo">assetInfo</param>
        /// <returns>Retruns Review Id</returns>
        public List <ProcessedFrameDetails> CreateVideoFrames(UploadAssetResult uploadAssetResult)
        {
            List <ProcessedFrameDetails> frameEventsList = new List <ProcessedFrameDetails>();

            PopulateFrameEvents(uploadAssetResult.ModeratedJson, frameEventsList, uploadAssetResult);
            return(frameEventsList);
        }
示例#2
0
        public async Task <string> CreateVideoReviewInContentModerator(UploadAssetResult uploadAssetResult)
        {
            string reviewId = string.Empty;
            List <ProcessedFrameDetails> frameEntityList = framegenerator.CreateVideoFrames(uploadAssetResult);
            string path = uploadAssetResult.GenerateVTT == true ? this._amsConfig.FfmpegFramesOutputPath + Path.GetFileNameWithoutExtension(uploadAssetResult.VideoName) + "_aud_SpReco.vtt" : "";
            TranscriptScreenTextResult screenTextResult = new TranscriptScreenTextResult();

            if (File.Exists(path))
            {
                screenTextResult = await GenerateTextScreenProfanity(reviewId, path, frameEntityList);

                uploadAssetResult.Category1TextScore = screenTextResult.Category1Score;
                uploadAssetResult.Category2TextScore = screenTextResult.Category2Score;
                uploadAssetResult.Category3TextScore = screenTextResult.Category3Score;
                uploadAssetResult.Category1TextTag   = screenTextResult.Category1Tag;
                uploadAssetResult.Category2TextTag   = screenTextResult.Category2Tag;
                uploadAssetResult.Category3TextTag   = screenTextResult.Category3Tag;
            }
            var reviewVideoRequestJson = CreateReviewRequestObject(uploadAssetResult, frameEntityList);

            if (string.IsNullOrWhiteSpace(reviewVideoRequestJson))
            {
                throw new Exception("Video review process failed in CreateVideoReviewInContentModerator");
            }
            var reviewIds = await ExecuteCreateReviewApi(reviewVideoRequestJson);

            reviewId        = reviewIds.FirstOrDefault();
            frameEntityList = framegenerator.GenerateFrameImages(frameEntityList, uploadAssetResult, reviewId);
            await CreateAndPublishReviewInContentModerator(uploadAssetResult, frameEntityList, reviewId, path, screenTextResult);

            return(reviewId);
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="uploadVideoRequest"></param>
        /// <param name="uploadResult"></param>
        /// <returns></returns>
        ///
        public bool CreateAzureMediaServicesJobToModerateVideo(UploadVideoStreamRequest uploadVideoRequest, UploadAssetResult uploadResult)
        {
            asset = CreateAsset(uploadVideoRequest);
            uploadResult.VideoName = uploadVideoRequest.VideoName;
            // Encoding the asset , Moderating the asset, Generating transcript in parallel
            IAsset encodedAsset = null;
            //Creates the job for the tasks.
            IJob job = this._mediaContext.Jobs.Create("AMS Review Job");

            //Adding encoding task to job.
            ConfigureEncodeAssetTask(uploadVideoRequest.EncodingRequest, job);

            ConfigureContentModerationTask(job);

            //adding transcript task to job.
            if (uploadResult.GenerateVTT)
            {
                ConfigureTranscriptTask(job);
            }

            var watch = System.Diagnostics.Stopwatch.StartNew();

            //submit and execute job.
            job.Submit();
            job.GetExecutionProgressTask(new CancellationTokenSource().Token).Wait();
            watch.Stop();
            Logger.Log($"AMS Job Elapsed Time: {watch.Elapsed}");

            if (job.State == JobState.Error)
            {
                throw new Exception("Video moderation has failed due to AMS Job error.");
            }

            UploadAssetResult result = uploadResult;

            encodedAsset         = job.OutputMediaAssets[0];
            result.ModeratedJson = GetCmDetail(job.OutputMediaAssets[1]);
            // Check for valid Moderated JSON
            var jsonModerateObject = JsonConvert.DeserializeObject <VideoModerationResult>(result.ModeratedJson);

            if (jsonModerateObject == null)
            {
                return(false);
            }
            if (uploadResult.GenerateVTT)
            {
                GenerateTranscript(job.OutputMediaAssets.Last());
            }

            uploadResult.StreamingUrlDetails = PublishAsset(encodedAsset);
            string downloadUrl = GenerateDownloadUrl(asset, uploadVideoRequest.VideoName);

            uploadResult.StreamingUrlDetails.DownloadUri = downloadUrl;
            uploadResult.VideoName     = uploadVideoRequest.VideoName;
            uploadResult.VideoFilePath = uploadVideoRequest.VideoFilePath;
            return(true);
        }
示例#4
0
        public async Task <string> CreateAndPublishReviewInContentModerator(UploadAssetResult assetinfo, List <ProcessedFrameDetails> frameEntityList, string reviewId, string path, TranscriptScreenTextResult screenTextResult)
        {
            bool isSuccess    = false;
            bool isTranscript = false;

            isSuccess = await SubmitAddFramesReview(frameEntityList, reviewId, assetinfo);

            if (!isSuccess)
            {
                Console.WriteLine("Add Frame API call failed.");
                throw new Exception();
            }

            if (File.Exists(path))
            {
                if (ValidateVtt(path))
                {
                    isTranscript = await SubmitTranscript(reviewId, path);
                }
                if (isTranscript)
                {
                    isSuccess = await UploadScreenTextResult(reviewId, JsonConvert.SerializeObject(screenTextResult?.TranscriptProfanity));

                    if (!isSuccess)
                    {
                        Console.WriteLine("ScreenTextResult API call failed.");
                        throw new Exception();
                    }
                }
                else
                {
                    Console.WriteLine("Upload vtt failed.");
                    throw new Exception();
                }
                try
                {
                    File.Delete(path);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            isSuccess = PublishReview(reviewId);
            if (!isSuccess)
            {
                throw new Exception("Publish review failed.");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("\nReview Created Successfully and the review Id {0}", reviewId);
            }
            CleanUp(reviewId);
            return(reviewId);
        }
示例#5
0
        /// <summary>
        /// Populates a Video frame object
        /// </summary>
        /// <param name="frameEvent">FrameEventBlobEntity</param>
        /// <returns>Video Frame Object</returns>
        private VideoFrame PopulateVideoFrame(ProcessedFrameDetails frameEvent, UploadAssetResult uploadResult)
        {
            VideoFrame frameobj = new VideoFrame()
            {
                FrameImage         = frameEvent.FrameName,
                Timestamp          = Convert.ToString(frameEvent.TimeStamp),
                ReviewerResultTags = new List <ReviewResultTag>(),
                Metadata           = new List <Metadata>()
                {
                    new Metadata()
                    {
                        Key = "Review Recommended", Value = frameEvent.ReviewRecommended.ToString()
                    },
                    new Metadata()
                    {
                        Key = "Adult Score", Value = frameEvent.AdultScore
                    },
                    new Metadata()
                    {
                        Key = "a", Value = frameEvent.IsAdultContent.ToString()
                    },
                    new Metadata()
                    {
                        Key = "Racy Score", Value = frameEvent.RacyScore
                    },
                    new Metadata()
                    {
                        Key = "r", Value = frameEvent.IsRacyContent.ToString()
                    },
                    new Metadata()
                    {
                        Key = "ExternalId", Value = frameEvent.FrameName
                    },
                    new Metadata()
                    {
                        Key = "at", Value = frameEvent.IsAdultTextContent.ToString()
                    },
                    new Metadata()
                    {
                        Key = "rt", Value = frameEvent.IsRacyTextContent.ToString()
                    },
                    new Metadata()
                    {
                        Key = "ot", Value = frameEvent.IsOffensiveTextContent.ToString()
                    }
                },
            };

            return(frameobj);
        }
        private static async Task ProcessVideo(string videoPath)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("\nVideo compression process started...");

            var compressedVideoPath = amsComponent.CompressVideo(videoPath);

            if (string.IsNullOrWhiteSpace(compressedVideoPath))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Video Compression failed.");
            }

            Console.WriteLine("\nVideo compression process completed...");

            UploadVideoStreamRequest uploadVideoStreamRequest = CreateVideoStreamingRequest(compressedVideoPath);
            UploadAssetResult        uploadResult             = new UploadAssetResult();

            if (generateVtt)
            {
                uploadResult.GenerateVTT = generateVtt;
            }
            Console.WriteLine("\nVideo moderation process started...");

            if (!videoModerator.CreateAzureMediaServicesJobToModerateVideo(uploadVideoStreamRequest, uploadResult))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("\nVideo moderation process failed.");
            }

            Console.WriteLine("\nVideo moderation process completed...");
            Console.WriteLine("\nVideo review process started...");

            string reviewId = await videoReviewApi.CreateVideoReviewInContentModerator(uploadResult);

            watch.Stop();

            Console.WriteLine("\nVideo review successfully completed...");
            Console.WriteLine("\nTotal Elapsed Time: {0}", watch.Elapsed);
            Logger.Log("Video File Name: " + Path.GetFileName(videoPath));
            Logger.Log($"ReviewId: {reviewId}");
            Logger.Log($"Total Elapsed Time: {watch.Elapsed}");
        }
示例#7
0
        /// <summary>
        /// Creates a review video request object.
        /// </summary>
        /// <param name="assetInfo">UploadAssetResult</param>
        /// <param name="frameEvents">List of FrameEventBlobEntity</param>
        /// <returns>Reviewvideo</returns>
        public string CreateReviewRequestObject(UploadAssetResult assetInfo, List <ProcessedFrameDetails> frameEvents)
        {
            List <ReviewVideo> reviewList     = new List <ReviewVideo>();
            ReviewVideo        reviewVideoObj = new ReviewVideo();

            try
            {
                reviewVideoObj.Type             = Constants.VideoEntityType;
                reviewVideoObj.Content          = assetInfo.StreamingUrlDetails.SmoothUrl;
                reviewVideoObj.ContentId        = assetInfo.VideoName;
                reviewVideoObj.CallbackEndpoint = this._amsConfig.ReviewCallBackUrl;
                reviewVideoObj.Metadata         = frameEvents.Count != 0 ? GenerateMetadata(frameEvents, assetInfo) : null;
                reviewVideoObj.Status           = Constants.PublishedStatus;
                reviewVideoObj.VideoFrames      = null;
                reviewList.Add(reviewVideoObj);
                return(JsonConvert.SerializeObject(reviewList));
            }
            catch (Exception e)
            {
                Console.WriteLine("An exception had occured at {0} ", MethodBase.GetCurrentMethod().Name);
                Console.WriteLine(e.Message);
                throw;
            }
        }
示例#8
0
        /// <summary>
        /// Forms the AddFrames request object.
        /// </summary>
        /// <param name="frameEvents">List of Frame events</param>
        /// <returns>Json representation of video frames collection.</returns>
        private string CreateAddFramesReviewRequestObject(List <ProcessedFrameDetails> frameEvents, UploadAssetResult uploadResult)
        {
            List <VideoFrame> videoFrames = GenerateVideoFrames(frameEvents, uploadResult);

            return(JsonConvert.SerializeObject(videoFrames));
        }
示例#9
0
        /// <summary>
        ///  Add frames and publishes it.
        /// </summary>
        /// <param name="frameEvents">List of Frame Events.</param>
        /// <param name="reviewId">Reviewid</param>
        /// <returns>Indicates Add frames operation success result.</returns>
        public async Task <bool> SubmitAddFramesReview(List <ProcessedFrameDetails> frameEvents, string reviewId, UploadAssetResult uploadResult)
        {
            bool          isSuccess    = true;
            int           batchSize    = _amsConfig.FrameBatchSize;
            var           batchFrames  = FetchFrameEvents(frameEvents, batchSize);
            List <string> frameRequest = new List <string>();

            foreach (var batchFrame in batchFrames)
            {
                frameRequest.Add(CreateAddFramesReviewRequestObject(batchFrame, uploadResult));
            }
            //string inputRequestObj = CreateAddFramesReviewRequestObject(frameEvents, uploadResult);
            string frameZipPath = $"{this._amsConfig.FfmpegFramesOutputPath}{reviewId}_zip";

            DirectoryInfo di = new DirectoryInfo(frameZipPath);

            FileInfo[] zipFiles = di.GetFiles();
            if (frameRequest.Count != zipFiles.Length)
            {
                Console.WriteLine("Something went wrong.");
                throw new Exception();
            }
            for (int i = 0; i < frameRequest.Count; i++)
            {
                int  retry      = 3;
                bool isComplete = false;
                HttpResponseMessage response;
                while (!isComplete && retry > 0)
                {
                    response = await ExecuteAddFramesReviewApi(reviewId, frameRequest[i], zipFiles[i].FullName);

                    isComplete = response.IsSuccessStatusCode;
                    retry--;
                    if (retry == 0 && !isComplete)
                    {
                        isSuccess = false;
                    }
                }
            }
            return(isSuccess);
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="frameEvents"></param>
        /// <returns></returns>
        private List <Metadata> GenerateMetadata(List <ProcessedFrameDetails> frameEvents, UploadAssetResult uploadResult)
        {
            List <Metadata> metadata          = new List <Metadata>();
            var             adultScore        = frameEvents.OrderByDescending(a => Double.Parse(a.AdultScore)).FirstOrDefault().AdultScore;
            var             racyScore         = frameEvents.OrderByDescending(a => Double.Parse(a.RacyScore)).FirstOrDefault().RacyScore;
            var             isAdult           = double.Parse(adultScore) > _amsConfig.AdultFrameThreshold ? true : false;
            var             isRacy            = double.Parse(racyScore) > _amsConfig.RacyFrameThreshold ? true : false;
            var             reviewRecommended = frameEvents.Any(frame => frame.ReviewRecommended);

            metadata = new List <Metadata>()
            {
                new Metadata()
                {
                    Key = "ReviewRecommended", Value = reviewRecommended.ToString()
                },
                new Metadata()
                {
                    Key = "AdultScore", Value = adultScore
                },
                new Metadata()
                {
                    Key = "a", Value = isAdult.ToString()
                },
                new Metadata()
                {
                    Key = "RacyScore", Value = racyScore
                },
                new Metadata()
                {
                    Key = "r", Value = isRacy.ToString()
                }
            };

            if (uploadResult.GenerateVTT)
            {
                metadata.AddRange(new List <Metadata>()
                {
                    new Metadata()
                    {
                        Key = "Category1TextScore", Value = uploadResult.Category1TextScore.ToString()
                    },
                    new Metadata()
                    {
                        Key = "at", Value = uploadResult.Category1TextTag.ToString()
                    },
                    new Metadata()
                    {
                        Key = "Category2TextScore", Value = uploadResult.Category2TextScore.ToString()
                    },
                    new Metadata()
                    {
                        Key = "rt", Value = uploadResult.Category2TextTag.ToString()
                    },
                    new Metadata()
                    {
                        Key = "Category3TextScore", Value = uploadResult.Category3TextScore.ToString()
                    },
                    new Metadata()
                    {
                        Key = "ot", Value = uploadResult.Category3TextTag.ToString()
                    }
                });
            }
            return(metadata);
        }
示例#11
0
        /// <summary>
        /// Geneartes Video Frames
        /// </summary>
        /// <param name="frameEvents">List of FrameEventBlobEntity</param>
        /// <returns>List of Video frames</returns>
        private List <VideoFrame> GenerateVideoFrames(List <ProcessedFrameDetails> frameEvents, UploadAssetResult uploadResult)
        {
            List <VideoFrame> videoFrames = new List <VideoFrame>();

            foreach (ProcessedFrameDetails frameEvent in frameEvents)
            {
                VideoFrame videoFrameObj = PopulateVideoFrame(frameEvent, uploadResult);
                videoFrames.Add(videoFrameObj);
            }
            return(videoFrames);
        }
        /// <summary>
        ///  GetGeneratedFrameList method used for Generating Frames using Moderated Json
        /// </summary>
        /// <param name="eventsList">resultDownloaddetailsList</param>
        /// <param name="assetInfo"></param>
        public List <ProcessedFrameDetails> GenerateFrameImages(List <ProcessedFrameDetails> eventsList, UploadAssetResult assetInfo, string reviewId)
        {
            string frameStorageLocalPath = this._amsConfig.FfmpegFramesOutputPath + reviewId;

            Directory.CreateDirectory(frameStorageLocalPath);
            int batchSize = _amsConfig.FrameBatchSize;

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("\nVideo Frames Creation inprogress...");
            var    watch         = System.Diagnostics.Stopwatch.StartNew();
            string ffmpegBlobUrl = string.Empty;

            if (File.Exists(_amsConfig.FfmpegExecutablePath))
            {
                ffmpegBlobUrl = _amsConfig.FfmpegExecutablePath;
            }

            List <string> args                = new List <string>();
            StringBuilder sb                  = new StringBuilder();
            int           frameCounter        = 0;
            int           frameProcessedCount = 0;
            int           segmentCount        = 0;
            string        dirPath             = string.Empty;

            foreach (var frame in eventsList)
            {
                if (frameProcessedCount % batchSize == 0)
                {
                    segmentCount = frameProcessedCount / batchSize;
                    dirPath      = $"{frameStorageLocalPath}\\{segmentCount}";
                    if (!Directory.Exists(dirPath))
                    {
                        Directory.CreateDirectory(dirPath);
                    }
                }
                frameProcessedCount++;
                frame.FrameName = reviewId + frame.FrameName;
                TimeSpan ts   = TimeSpan.FromMilliseconds(Convert.ToDouble(frame.TimeStamp));
                var      line = "-ss " + ts + " -i \"" + assetInfo.VideoFilePath + "\" -map " + frameCounter + ":v -frames:v 1 -vf scale=320:-1 \"" + dirPath + "\\" + frame.FrameName + "\" ";
                frameCounter++;
                sb.Append(line);
                if (sb.Length > 30000)
                {
                    args.Add(sb.ToString());
                    sb.Clear();
                    frameCounter = 0;
                }
            }
            if (sb.Length != 0)
            {
                args.Add(sb.ToString());
            }

            Parallel.ForEach(args, new ParallelOptions {
                MaxDegreeOfParallelism = 4
            },
                             arg => CreateTaskProcess(arg, ffmpegBlobUrl));

            watch.Stop();
            Logger.Log($"Frame Creation Elapsed time: {watch.Elapsed}");
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WriteLine("Frames(" + eventsList.Count() + ") created successfully.");
            DirectoryInfo[] diArr = new DirectoryInfo(frameStorageLocalPath).GetDirectories();
            Directory.CreateDirectory(frameStorageLocalPath + @"_zip");
            foreach (var dir in diArr)
            {
                ZipFile.CreateFromDirectory(dir.FullName, frameStorageLocalPath + $"_zip\\{dir.Name}.zip");
            }
            return(eventsList);
        }
        /// <summary>
        /// Generates frames based on moderated json source.
        /// </summary>
        /// <param name="moderatedJsonstring">moderatedJsonstring</param>
        /// <param name="resultEventDetailsList">resultEventDetailsList</param>

        private void PopulateFrameEvents(string moderatedJsonstring, List <ProcessedFrameDetails> resultEventDetailsList, UploadAssetResult uploadResult)
        {
            var jsonModerateObject = JsonConvert.DeserializeObject <VideoModerationResult>(moderatedJsonstring);

            if (jsonModerateObject != null)
            {
                var timeScale  = Convert.ToInt32(jsonModerateObject.TimeScale);
                int frameCount = 0;
                foreach (var item in jsonModerateObject.Fragments)
                {
                    if (item.Events != null)
                    {
                        foreach (var frameEventDetailList in item.Events)
                        {
                            foreach (FrameEventDetails frameEventDetails in frameEventDetailList)
                            {
                                var eventDetailsObj = new ProcessedFrameDetails
                                {
                                    ReviewRecommended = frameEventDetails.ReviewRecommended,
                                    TimeStamp         = (frameEventDetails.TimeStamp * 1000 / timeScale),
                                    IsAdultContent    = double.Parse(frameEventDetails.AdultScore) > _amsConfig.AdultFrameThreshold ? true : false,
                                    AdultScore        = frameEventDetails.AdultScore,
                                    IsRacyContent     = double.Parse(frameEventDetails.RacyScore) > _amsConfig.RacyFrameThreshold ? true : false,
                                    RacyScore         = frameEventDetails.RacyScore,
                                    TimeScale         = timeScale,
                                };
                                frameCount++;
                                eventDetailsObj.FrameName = "_" + frameCount + ".jpg";
                                resultEventDetailsList.Add(eventDetailsObj);
                            }
                        }
                    }
                }
            }
        }