public static async Task RunAsync( [QueueTrigger("%EncodingCompleteQueue%", Connection = "AzureWebJobsStorage")] string myQueueItem, TraceWriter log) { var videoIndexerHelper = new VideoIndexerHelper(log); var cosmosHelper = new CosmosHelper(log); var msg = JsonConvert.DeserializeObject <NotificationMessage>(myQueueItem); if (msg.EventType != NotificationEventType.TaskStateChange) { return; // ignore anything but job complete } var newJobStateStr = msg.Properties.FirstOrDefault(j => j.Key == Constants.NEWSTATE).Value; if (newJobStateStr == Enums.StateEnum.Finished.ToString()) { var jobId = msg.Properties["JobId"]; var taskId = msg.Properties["TaskId"]; _context = MediaServicesHelper.Context; var job = _context.Jobs.Where(j => j.Id == jobId).FirstOrDefault(); if (job == null) { videoIndexerHelper.LogMessage($"Job for JobId:{jobId} is null"); return; } var task = job.Tasks.Where(l => l.Id == taskId).FirstOrDefault(); if (task == null) { videoIndexerHelper.LogMessage($"Task for taskId:{taskId} is null"); return; } var outputAsset = task.OutputAssets[0]; var inputAsset = task.InputAssets[0]; cosmosHelper.LogMessage("Read policy"); var readPolicy = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromHours(4), AccessPermissions.Read); var outputLocator = _context.Locators.CreateLocator(LocatorType.Sas, outputAsset, readPolicy); cosmosHelper.LogMessage("Create cloud blob client"); var destBlobStorage = BlobHelper.AmsStorageAccount.CreateCloudBlobClient(); cosmosHelper.LogMessage("get asset container"); // Get the asset container reference var outContainerName = new Uri(outputLocator.Path).Segments[1]; var outContainer = destBlobStorage.GetContainerReference(outContainerName); cosmosHelper.LogMessage("use largest single mp4 "); // use largest single mp4 output (highest bitrate) to send to Video Indexer var biggestblob = outContainer.ListBlobs().OfType <CloudBlockBlob>() .Where(b => b.Name.ToLower().EndsWith(".mp4")) .OrderBy(u => u.Properties.Length).Last(); cosmosHelper.LogMessage("GetSasUrl"); var sas = videoIndexerHelper.GetSasUrl(biggestblob); cosmosHelper.LogMessage(" submit to VI "); // Submit processing job to Video Indexer await videoIndexerHelper.SubmitToVideoIndexerAsync(biggestblob.Name, sas, inputAsset.AlternateId, log); } }
public static async Task RunAsync( [QueueTrigger("%VIProcessingCompleteQueue%", Connection = "AzureWebJobsStorage")] CloudQueueMessage myQueueItem, TraceWriter log) { var videoIndexerHelper = new VideoIndexerHelper(log); var cosmosHelper = new CosmosHelper(log); var queueContents = myQueueItem.AsString; // queue item should be id & state var completionData = JsonConvert.DeserializeObject <Dictionary <string, string> >(queueContents); // ignore if not proper state if (completionData["state"] != "Processed") { return; } var videoIndexerVideoId = completionData["id"]; var apiUrl = videoIndexerHelper.VideoIndexerApiUrl; var client = videoIndexerHelper.GetVideoIndexerHttpClient(); var uri = string.Format(apiUrl + "/{0}", videoIndexerVideoId); videoIndexerHelper.LogMessage($" call VI with uri{uri}"); var response = await client.GetAsync(uri); var json = await response.Content.ReadAsStringAsync(); videoIndexerHelper.LogMessage($"get state with id: {videoIndexerVideoId}"); var state = cosmosHelper.GetManifestStateRecordByVideoId(videoIndexerVideoId, log); videoIndexerHelper.LogMessage("create poco from json "); var videoBreakdownPoco = JsonConvert.DeserializeObject <VideoBreakdown>(json); var taskList = new List <Task>(); // these tasks are network io dependant and can happen in parallel //TODO: setup default languages to be pulled from app settings, but //TODO: the languages set in config would override //TODO: validate languages videoIndexerHelper.LogMessage("Process transcripts"); if (state.Transcripts != null) { taskList = state.Transcripts .Select(language => GetCaptionsVttAsync(videoIndexerVideoId, videoBreakdownPoco, language, videoIndexerHelper)) .ToList(); } videoIndexerHelper.LogMessage("start task extract images"); taskList.Add(ExtractImages(videoBreakdownPoco, log, videoIndexerHelper)); //var englishCaptionsTask = GetCaptionsVttAsync(videoIndexerVideoId, videoBreakdownPoco, "English"); //var japaneseCaptionsTask = GetCaptionsVttAsync(videoIndexerVideoId, videoBreakdownPoco, "Japanese"); //var imagesTask = ExtractImages(videoBreakdownPoco); videoIndexerHelper.LogMessage($"wait for tasks to finish"); await Task.WhenAll(taskList.ToArray()); videoIndexerHelper.LogMessage($"store in json breakdowns"); // we wait to store breakdown json because it's modified in previous tasks var storeTask1 = StoreBreakdownJsonInCosmos(videoBreakdownPoco, log); videoIndexerHelper.LogMessage($"update processing "); var storeTask2 = cosmosHelper.UpdateProcessingStateAsync(completionData["id"]); videoIndexerHelper.LogMessage($"wait for store tasks to finish"); await Task.WhenAll(storeTask1, storeTask2); }