private static async Task <string> UploadVideoReview(VisualModerationResult vmResult, TextModerationResult tmResult) { Console.WriteLine("[Content Moderator] Video Review publishing started..."); string reviewId = string.Empty; string videoFilePath = vmResult.VideoFilePath; try { reviewId = await videoReviewUploader.CreateVideoReview(vmResult, tmResult); await videoReviewUploader.AddVideoFramesToVideoReview(vmResult, reviewId); await videoReviewUploader.AddVideoTranscriptToVideoReview(tmResult, reviewId); await videoReviewUploader.AddVideoTranscriptModerationResultToVideoReview(tmResult, reviewId); await videoReviewUploader.PublishVideoReview(reviewId); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Content Moderator] Video Review publishing failed. Error: ", e.ToString()); Console.ForegroundColor = ConsoleColor.White; } FFmpegComponent.CleanUp(videoFilePath, reviewId); Console.WriteLine("[Content Moderator] Video Review published Successfully and the review Id {0}", reviewId); return(reviewId); }
public async Task <string> CreateVideoReviewWithContentModeratorReviewAPI(VisualModerationResult vmResult, List <FrameEvent> frameEventList) { string reviewId = string.Empty; try { string videoReviewsJson = CreateVideoReviewObject(vmResult, frameEventList); if (string.IsNullOrWhiteSpace(videoReviewsJson)) { throw new Exception("VideoReview process failed in CreateVideoReview"); } List <CreateVideoReviewsBodyItem> review = JsonConvert.DeserializeObject <List <CreateVideoReviewsBodyItem> >(videoReviewsJson); var res = await this.client.Reviews.CreateVideoReviewsWithHttpMessagesAsync("application/json", reviewToolConfig.TeamId, review); if (res.Response.StatusCode != System.Net.HttpStatusCode.OK) { throw new Exception("CreateVideoReviewWithContentModeratorReviewAPI has failed to get a Video Review. Code: " + res.Response.StatusCode); } List <string> reviewIds = res.Body.ToList(); reviewId = reviewIds.FirstOrDefault(); } catch (Exception e) { Console.WriteLine(e.Message); throw; } return(reviewId); }
private static async Task <VisualModerationResult> ProcessVideoModeration(string compressedVideoPath) { Console.WriteLine("[Content Moderator] Video moderation process started..."); VisualModerationResult result = await visualModerator.ModerateVideo(compressedVideoPath); if (result == null) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[Content Moderator] Video moderation process failed."); Console.ForegroundColor = ConsoleColor.White; } Console.WriteLine("[Content Moderator] Video moderation process completed..."); return(result); }
public async Task <string> CreateVideoReview(VisualModerationResult vmResult, TextModerationResult tmResult) { // Step 1 - Create Video Review string reviewId = string.Empty; List <FrameEvent> frameEventList = ExtractFrameEventListFromJson(vmResult.VisualModeratedJson); frameEventList = MergeTextModerationResultToFrameEventList(frameEventList, tmResult.captionTextResults); reviewId = await CreateVideoReviewWithContentModeratorReviewAPI(vmResult, frameEventList); this.frameEventList = FixFrameNameInFrameEventList(frameEventList, reviewId); return(reviewId); }
private List <VideoReview> GenerateVideoReviewList(VisualModerationResult vmResult, List <FrameEvent> frameEventList) { List <VideoReview> videoReviewList = new List <VideoReview>(); VideoReview videoReviewObj = new VideoReview(); videoReviewObj.Type = VideoEntityType; videoReviewObj.Content = vmResult.StreamingUrlDetails.SmoothUri; videoReviewObj.ContentId = vmResult.VideoName; videoReviewObj.CallbackEndpoint = null; videoReviewObj.Metadata = frameEventList.Count != 0 ? GenerateVideoReviewMetadata(frameEventList) : null;; videoReviewObj.Status = UnpublishedStatus; videoReviewObj.VideoFrames = null; videoReviewList.Add(videoReviewObj); return(videoReviewList); }
private VisualModerationResult CreateVisualModeratorResult(IAzureMediaServicesClient client, string resourceGroup, string accountName, string videoStreamingLocatorName, string analysisStreamingLocatorName) { VisualModerationResult result = new VisualModerationResult(); result.StreamingUrlDetails = new PublishedUrlDetails(); var streamingEndpoint = client.StreamingEndpoints.Get(resourceGroup, accountName, "default"); UriBuilder uriBuilder = new UriBuilder(); uriBuilder.Scheme = "https"; uriBuilder.Host = streamingEndpoint.HostName; var paths = client.StreamingLocators.ListPaths(resourceGroup, accountName, videoStreamingLocatorName); for (int i = 0; i < paths.StreamingPaths.Count; i++) { if (paths.StreamingPaths[i].Paths.Count > 0) { if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.SmoothStreaming) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.SmoothUri = uriBuilder.ToString(); } else if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.Dash) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.MpegDashUri = uriBuilder.ToString(); } else if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.Hls) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.HlsUri = uriBuilder.ToString(); } } } var dlpaths = client.StreamingLocators.ListPaths(resourceGroup, accountName, analysisStreamingLocatorName); for (int i = 0; i < dlpaths.DownloadPaths.Count; i++) { if (dlpaths.DownloadPaths[i].EndsWith("transcript.vtt")) { uriBuilder.Path = dlpaths.DownloadPaths[i]; result.StreamingUrlDetails.VttUrl = uriBuilder.ToString(); } } return(result); }
public async Task <string> AddVideoFramesToVideoReview(VisualModerationResult result, string reviewId) { // Step 2 (a) - Add Video Frames to Video Review bool isSuccess = true; List <List <FrameEvent> > segmentedFrameEventList = GenerateBatchSegmentsOfFrameEventList(this.frameEventList, SegmentSizeOfFrameEvents); string frameZipFilesPath = GenerateFrameImages(segmentedFrameEventList, reviewId, result.VideoFilePath); isSuccess = await AddVideoFramesToReviewWithContentModeratorReviewAPI(reviewId, segmentedFrameEventList, frameZipFilesPath); if (!isSuccess) { throw new Exception("AddVideoFramesToReviewWithContentModeratorReviewAPI call failed."); } return(reviewId); }
static void Main(string[] args) { ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build()); VisualModerator visualModerator = new VisualModerator(config); string videoPath = "https://shigeyfampdemo.azurewebsites.net/videos/ignite.mp4"; try { Task <VisualModerationResult> task = visualModerator.ModerateVideo(videoPath); VisualModerationResult result = task.Result; } catch (Exception e) { Console.WriteLine("Error: ", e.ToString()); } Console.WriteLine("Visual Modeation has finished."); Console.WriteLine("Press any key to stop..."); Console.ReadKey(); }
public async Task <VisualModerationResult> ModerateVideo(string videoPath) { string resourceGroup = this.visualModeratorConfig.ResourceGroup; string accountName = this.visualModeratorConfig.AccountName; IAzureMediaServicesClient client = await CreateMediaServicesClientAsync(); VisualModerationResult result = null; try { string uniqueness = Guid.NewGuid().ToString(); string jobName = "job-" + uniqueness; string inputAssetName = "asset-input-" + uniqueness; string outputAssetName1 = "asset-output-video-" + uniqueness; string outputAssetName2 = "asset-output-analysis-" + uniqueness; string streamingLocatorName1 = "streaminglocator-video-" + uniqueness; string streamingLocatorName2 = "streaminglocator-analysis-" + uniqueness; Transform videoAnalyzerTransform = EnsureTransformExists(client, resourceGroup, accountName, VisualModerationTransformName); CreateInputAsset(client, resourceGroup, accountName, inputAssetName, videoPath).Wait(); Asset outputAsset1 = CreateOutputAsset(client, resourceGroup, accountName, outputAssetName1); Asset outputAsset2 = CreateOutputAsset(client, resourceGroup, accountName, outputAssetName2); JobInput jobInput = new JobInputAsset(assetName: inputAssetName); JobOutput[] jobOutputs = { new JobOutputAsset(outputAsset1.Name), new JobOutputAsset(outputAsset2.Name), }; Job job = SubmitJob(client, resourceGroup, accountName, VisualModerationTransformName, jobName, jobInput, jobOutputs); job = WaitForJobToFinish(client, resourceGroup, accountName, VisualModerationTransformName, jobName); if (job.State == JobState.Finished) { Console.WriteLine("\nAMSv3 Job finished."); PublishStreamingAsset(client, resourceGroup, accountName, outputAsset1.Name, streamingLocatorName1); PublishDownloadAsset(client, resourceGroup, accountName, outputAsset2.Name, streamingLocatorName2); result = CreateVisualModeratorResult(client, resourceGroup, accountName, streamingLocatorName1, streamingLocatorName2); result.VideoName = outputAssetName1; result.VideoFilePath = videoPath; result.AccessToken = null; result.VisualModeratedJson = await GetVisualModerationJsonFile(client, resourceGroup, accountName, outputAsset2.Name); } else if (job.State == JobState.Error) { Console.WriteLine($"ERROR: Job finished with error message: {job.Outputs[0].Error.Message}"); Console.WriteLine($"ERROR: error details: {job.Outputs[0].Error.Details[0].Message}"); } } catch (ApiErrorException ex) { string code = ex.Body.Error.Code; string message = ex.Body.Error.Message; Console.WriteLine("ERROR:API call failed with error code: {0} and message: {1}", code, message); } return(result); }
private string CreateVideoReviewObject(VisualModerationResult vmResult, List <FrameEvent> frameEventList) { List <VideoReview> videoReviews = GenerateVideoReviewList(vmResult, frameEventList); return(JsonConvert.SerializeObject(videoReviews)); }
public async Task <VisualModerationResult> ModerateVideo(string videoPath) { string resourceGroup = this.visualModeratorConfig.ResourceGroup; string accountName = this.visualModeratorConfig.AccountName; IAzureMediaServicesClient client = await CreateMediaServicesClientAsync(); // Set the polling interval for long running operations to 2 seconds. // The default value is 30 seconds for the .NET client SDK client.LongRunningOperationRetryTimeout = 2; VisualModerationResult result = null; try { string uniqueness = Guid.NewGuid().ToString(); string jobName = JobNamePrefix + uniqueness; string streamingOutputAssetName = VideoOutputAssetNamePrefix + uniqueness; string analyticsOutputAssetName = AnalyticsOutputAssetNamePrefix + uniqueness; JobInput jobInput = null; List <Asset> outputAssetList = new List <Asset>(); Transform videoAnalyzerTransform = EnsureTransformExists(client, resourceGroup, accountName, VisualModerationTransformName); if (videoPath.StartsWith("http://") || videoPath.StartsWith("https://")) { Uri inputVideoUri = new Uri(videoPath); string baseUri = inputVideoUri.Scheme + "://" + inputVideoUri.Host; for (int i = 0; i < inputVideoUri.Segments.Length - 1; i++) { baseUri = baseUri + inputVideoUri.Segments[i]; } jobInput = new JobInputHttp( baseUri: baseUri, files: new List <String> { inputVideoUri.Segments[inputVideoUri.Segments.Length - 1] }, label: JobInputLabel ); } else { string inputAssetName = InputAssetNamePrefix + uniqueness; CreateInputAssetWithUploading(client, resourceGroup, accountName, inputAssetName, videoPath).Wait(); jobInput = new JobInputAsset(assetName: inputAssetName, label: JobInputLabel); } List <JobOutput> jobOutputList = new List <JobOutput>(); Asset analyticsOutputAsset = CreateOutputAsset(client, resourceGroup, accountName, analyticsOutputAssetName); outputAssetList.Add(analyticsOutputAsset); jobOutputList.Add(new JobOutputAsset(assetName: analyticsOutputAsset.Name, label: JobAnalyticsOutputLabel)); if (this.visualModeratorConfig.EnableStreamingVideo) { Asset streamingOutputAsset = CreateOutputAsset(client, resourceGroup, accountName, streamingOutputAssetName); outputAssetList.Add(streamingOutputAsset); jobOutputList.Add(new JobOutputAsset(assetName: streamingOutputAsset.Name, label: JobVideoOutputLabel)); } JobOutput[] jobOutputs = jobOutputList.ToArray(); Job job = SubmitJob(client, resourceGroup, accountName, videoAnalyzerTransform.Name, jobName, jobInput, jobOutputs); job = WaitForJobToFinish(client, resourceGroup, accountName, videoAnalyzerTransform.Name, jobName); if (job.State == JobState.Finished) { Console.WriteLine("\nAMSv3 Job finished."); List <StreamingLocator> locators = PublishAssets(client, resourceGroup, accountName, jobOutputList); result = CreateVisualModeratorResult(client, resourceGroup, accountName, videoPath, locators); using (var webClient = new WebClient()) { webClient.Encoding = Encoding.UTF8; result.VisualModerationJson = webClient.DownloadString(result.StreamingUrlDetails.ContentModerationJsonUrl); result.OcrJson = webClient.DownloadString(result.StreamingUrlDetails.OcrJsonUrl); } } else if (job.State == JobState.Error) { Console.WriteLine($"ERROR: Job finished with error message: {job.Outputs[0].Error.Message}"); Console.WriteLine($"ERROR: error details: {job.Outputs[0].Error.Details[0].Message}"); } } catch (ApiErrorException ex) { string code = ex.Body.Error.Code; string message = ex.Body.Error.Message; Console.WriteLine("ERROR:API call failed with error code: {0} and message: {1}", code, message); } return(result); }
private VisualModerationResult CreateVisualModeratorResult(IAzureMediaServicesClient client, string resourceGroup, string accountName, string videoPath, List <StreamingLocator> locators) { VisualModerationResult result = new VisualModerationResult(); result.StreamingUrlDetails = new PublishedUrlDetails(); result.VideoFilePath = videoPath; var streamingEndpoint = client.StreamingEndpoints.Get(resourceGroup, accountName, "default"); UriBuilder uriBuilder = new UriBuilder(); uriBuilder.Scheme = "https"; uriBuilder.Host = streamingEndpoint.HostName; foreach (var locator in locators) { if (locator.Name.StartsWith(VideoStreamingLocatorPrefix)) { var paths = client.StreamingLocators.ListPaths(resourceGroup, accountName, locator.Name); for (int i = 0; i < paths.StreamingPaths.Count; i++) { if (paths.StreamingPaths[i].Paths.Count > 0) { if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.SmoothStreaming) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.SmoothUri = uriBuilder.ToString(); } else if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.Dash) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.MpegDashUri = uriBuilder.ToString(); } else if (paths.StreamingPaths[i].StreamingProtocol == StreamingPolicyStreamingProtocol.Hls) { uriBuilder.Path = paths.StreamingPaths[i].Paths[0]; result.StreamingUrlDetails.HlsUri = uriBuilder.ToString(); } } } result.VideoName = locator.Name; result.AccessToken = null; } else if (locator.Name.StartsWith(AnalyticsStreamingLocatorPrefix)) { var dlpaths = client.StreamingLocators.ListPaths(resourceGroup, accountName, locator.Name); for (int i = 0; i < dlpaths.DownloadPaths.Count; i++) { if (dlpaths.DownloadPaths[i].EndsWith("transcript.vtt")) { uriBuilder.Path = dlpaths.DownloadPaths[i]; result.StreamingUrlDetails.VttUrl = uriBuilder.ToString(); } else if (dlpaths.DownloadPaths[i].EndsWith("contentmoderation.json")) { uriBuilder.Path = dlpaths.DownloadPaths[i]; result.StreamingUrlDetails.VttUrl = uriBuilder.ToString(); } else if (dlpaths.DownloadPaths[i].EndsWith("ocr.json")) { uriBuilder.Path = dlpaths.DownloadPaths[i]; result.StreamingUrlDetails.VttUrl = uriBuilder.ToString(); } } } } return(result); }