public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log) { { log.Info($"Webhook was triggered!"); string jsonContent = await req.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonContent); log.Info(jsonContent); if (data.assetId == null) { // for test // data.assetId = "nb:cid:UUID:c0d770b4-1a69-43c4-a4e6-bc60d20ab0b2"; return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass asset ID in the input object (assetId)" })); } string playerUrl = ""; string smoothUrl = ""; string pathUrl = ""; string preferredSE = data.preferredSE; string serveType = data.serveType; MediaServicesCredentials amsCredentials = new MediaServicesCredentials(); log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}"); try { AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain, new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret), AzureEnvironments.AzureCloudEnvironment); AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials); _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider); // Get the asset string assetid = data.assetId; var outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault(); if (outputAsset == null) { log.Info($"Asset not found {assetid}"); return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" })); } // publish with a streaming locator (100 years) log.Info(serveType); if (serveType == "OnDemandOrigin") { IAccessPolicy readPolicy2 = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromDays(365 * 100), AccessPermissions.Read); ILocator outputLocator2 = _context.Locators.CreateLocator(LocatorType.OnDemandOrigin, outputAsset, readPolicy2); var publishurlsmooth = MediaServicesHelper.GetValidOnDemandURI(_context, outputAsset, preferredSE); var publishurlpath = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset, preferredSE); if (outputLocator2 != null && publishurlsmooth != null) { smoothUrl = publishurlsmooth.ToString(); playerUrl = "https://ampdemo.azureedge.net/?url=" + HttpUtility.UrlEncode(smoothUrl); log.Info($"smooth url : {smoothUrl}"); } if (outputLocator2 != null && publishurlpath != null) { pathUrl = publishurlpath.ToString(); log.Info($"path url : {pathUrl}"); } } if (serveType == "sas") { IAccessPolicy readPolicy1 = _context.AccessPolicies.Create("readPolicy", TimeSpan.FromDays(365 * 100), AccessPermissions.Read); ILocator outputLocator1 = _context.Locators.CreateLocator(LocatorType.Sas, outputAsset, readPolicy1); } } catch (Exception ex) { string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : ""); log.Info($"ERROR: Exception {message}"); return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message })); } log.Info($""); return(req.CreateResponse(HttpStatusCode.OK, new { playerUrl = playerUrl, smoothUrl = smoothUrl, pathUrl = pathUrl })); } }
public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log) { { log.Info($"Webhook was triggered!"); // Init variables string pathUrl = ""; dynamic pngThumbnails = new JArray() as dynamic; string prefixpng = ""; string copyToContainer = ""; string targetContainerUri = ""; TimeSpan timeOffset = new TimeSpan(0); string jsonContent = await req.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonContent); var attachedstoragecred = KeyHelper.ReturnStorageCredentials(); log.Info(jsonContent); MediaServicesCredentials amsCredentials = new MediaServicesCredentials(); log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}"); try { AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain, new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret), AzureEnvironments.AzureCloudEnvironment); AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials); _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider); // // MES Thumbnails // if (data.mesThumbnails != null && data.mesThumbnails.assetId != null) { List <CloudBlob> listPNGCopies = new List <CloudBlob>(); // Get the asset string assetid = data.mesThumbnails.assetId; var outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault(); if (outputAsset == null) { log.Info($"Asset not found {assetid}"); return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" })); } var pngFiles = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".PNG")); Uri publishurl = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset); if (publishurl != null) { pathUrl = publishurl.ToString(); } else { log.Info($"Asset not published"); } // Let's copy the PNG Thumbnails if (data.mesThumbnails.copyToContainer != null) { copyToContainer = data.mesThumbnails.copyToContainer + DateTime.UtcNow.ToString("yyyyMMdd"); // let's copy PNG to a container prefixpng = outputAsset.Uri.Segments[1] + "-"; log.Info($"prefixpng {prefixpng}"); string storname = amsCredentials.StorageAccountName; string storkey = amsCredentials.StorageAccountKey; if (outputAsset.StorageAccountName != amsCredentials.StorageAccountName) { if (attachedstoragecred.ContainsKey(outputAsset.StorageAccountName)) // asset is using another storage than default but we have the key { storname = outputAsset.StorageAccountName; storkey = attachedstoragecred[storname]; } else // we don't have the key for that storage { log.Info($"MES Thumbnails Asset is in {outputAsset.StorageAccountName} and key is not provided in MediaServicesAttachedStorageCredentials application settings"); return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Storage key is missing" })); } } var sourceContainer = CopyBlobHelpers.GetCloudBlobContainer(storname, storkey, outputAsset.Uri.Segments[1]); CloudBlobContainer targetContainer; if (data.mesThumbnails.copyToContainerAccountName != null) { // copy to a specific storage account targetContainer = CopyBlobHelpers.GetCloudBlobContainer((string)data.mesThumbnails.copyToContainerAccountName, (string)data.mesThumbnails.copyToContainerAccountKey, copyToContainer); } else { // copy to ams storage account targetContainer = CopyBlobHelpers.GetCloudBlobContainer(amsCredentials.StorageAccountName, amsCredentials.StorageAccountKey, copyToContainer); } listPNGCopies = await CopyBlobHelpers.CopyFilesAsync(sourceContainer, targetContainer, prefixpng, "png", log); targetContainerUri = targetContainer.Uri.ToString(); } foreach (IAssetFile file in pngFiles) { string index = file.Name.Substring(file.Name.Length - 10, 6); int index_i = 0; if (int.TryParse(index, out index_i)) { dynamic entry = new JObject(); entry.id = index_i; entry.fileId = file.Id; entry.fileName = file.Name; if (copyToContainer != "") { entry.url = targetContainerUri + "/" + prefixpng + file.Name; } else if (!string.IsNullOrEmpty(pathUrl)) { entry.url = pathUrl + file.Name; } pngThumbnails.Add(entry); } } if (data.mesThumbnails.deleteAsset != null && ((bool)data.mesThumbnails.deleteAsset)) { // If asset deletion was asked // let's wait for the copy to finish before deleting the asset.. if (listPNGCopies.Count > 0) { log.Info("PNG Copy with asset deletion was asked. Checking copy status..."); bool continueLoop = true; while (continueLoop) { listPNGCopies = listPNGCopies.Where(r => r.CopyState.Status == CopyStatus.Pending).ToList(); if (listPNGCopies.Count == 0) { continueLoop = false; } else { log.Info("PNG Copy not finished. Waiting 3s..."); Task.Delay(TimeSpan.FromSeconds(3d)).Wait(); listPNGCopies.ForEach(r => r.FetchAttributes()); } } } outputAsset.Delete(); } } } catch (Exception ex) { string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : ""); log.Info($"ERROR: Exception {message}"); return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message })); } log.Info($""); return(req.CreateResponse(HttpStatusCode.OK, new { mesThumbnail = new { pngThumbnails = Newtonsoft.Json.JsonConvert.SerializeObject(pngThumbnails) } })); } }
public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log) { { log.Info($"Webhook was triggered!"); // Init variables string vttUrl = ""; string pathUrl = ""; string ttmlUrl = ""; string vttContent = ""; string ttmlContent = ""; string ttmlContentTimeCorrected = ""; string vttContentTimeCorrected = ""; string jsonContent = await req.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonContent); log.Info(jsonContent); if (data.assetId == null) { // for test // data.assetId = "nb:cid:UUID:d9496372-32f5-430d-a4c6-d21ec3e01525"; return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Please pass asset ID in the input object (AssetId)" })); } MediaServicesCredentials amsCredentials = new MediaServicesCredentials(); log.Info($"Using Azure Media Service Rest API Endpoint : {amsCredentials.AmsRestApiEndpoint}"); try { AzureAdTokenCredentials tokenCredentials = new AzureAdTokenCredentials(amsCredentials.AmsAadTenantDomain, new AzureAdClientSymmetricKey(amsCredentials.AmsClientId, amsCredentials.AmsClientSecret), AzureEnvironments.AzureCloudEnvironment); AzureAdTokenProvider tokenProvider = new AzureAdTokenProvider(tokenCredentials); _context = new CloudMediaContext(amsCredentials.AmsRestApiEndpoint, tokenProvider); // Get the asset string assetid = data.assetId; var outputAsset = _context.Assets.Where(a => a.Id == assetid).FirstOrDefault(); if (outputAsset == null) { log.Info($"Asset not found {assetid}"); return(req.CreateResponse(HttpStatusCode.BadRequest, new { error = "Asset not found" })); } var vttSubtitle = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".VTT")).FirstOrDefault(); var ttmlSubtitle = outputAsset.AssetFiles.Where(a => a.Name.ToUpper().EndsWith(".TTML")).FirstOrDefault(); Uri publishurl = MediaServicesHelper.GetValidOnDemandPath(_context, outputAsset); if (publishurl != null) { pathUrl = publishurl.ToString(); } else { log.Info($"Asset not published"); } if (vttSubtitle != null) { if (publishurl != null) { vttUrl = pathUrl + vttSubtitle.Name; log.Info($"vtt url : {vttUrl}"); } vttContent = MediaServicesHelper.ReturnContent(vttSubtitle); if (data.timeOffset != null) // let's update the ttml with new timecode { var tsoffset = TimeSpan.Parse((string)data.timeOffset); string arrow = " --> "; StringBuilder sb = new StringBuilder(); string[] delim = { Environment.NewLine, "\n" }; // "\n" added in case you manually appended a newline string[] vttlines = vttContent.Split(delim, StringSplitOptions.None); foreach (string vttline in vttlines) { string line = vttline; if (vttline.Contains(arrow)) { TimeSpan begin = TimeSpan.Parse(vttline.Substring(0, vttline.IndexOf(arrow))); TimeSpan end = TimeSpan.Parse(vttline.Substring(vttline.IndexOf(arrow) + 5)); line = (begin + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff") + arrow + (end + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff"); } sb.AppendLine(line); } vttContentTimeCorrected = sb.ToString(); } } if (ttmlSubtitle != null) { if (publishurl != null) { ttmlUrl = pathUrl + vttSubtitle.Name; log.Info($"ttml url : {ttmlUrl}"); } ttmlContent = MediaServicesHelper.ReturnContent(ttmlSubtitle); if (data.timeOffset != null) // let's update the vtt with new timecode { var tsoffset = TimeSpan.Parse((string)data.timeOffset); log.Info("tsoffset : " + tsoffset.ToString(@"d\.hh\:mm\:ss\.fff")); XNamespace xmlns = "http://www.w3.org/ns/ttml"; XDocument docXML = XDocument.Parse(ttmlContent); var tt = docXML.Element(xmlns + "tt"); var subtitles = docXML.Element(xmlns + "tt").Element(xmlns + "body").Element(xmlns + "div").Elements(xmlns + "p"); foreach (var sub in subtitles) { var begin = TimeSpan.Parse((string)sub.Attribute("begin")); var end = TimeSpan.Parse((string)sub.Attribute("end")); sub.SetAttributeValue("end", (end + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff")); sub.SetAttributeValue("begin", (begin + tsoffset).ToString(@"d\.hh\:mm\:ss\.fff")); } ttmlContentTimeCorrected = docXML.Declaration.ToString() + Environment.NewLine + docXML.ToString(); } } if (ttmlContent != "" && vttContent != "" && data.deleteAsset != null && ((bool)data.deleteAsset)) // If asset deletion was asked { outputAsset.Delete(); } } catch (Exception ex) { string message = ex.Message + ((ex.InnerException != null) ? Environment.NewLine + MediaServicesHelper.GetErrorMessage(ex) : ""); log.Info($"ERROR: Exception {message}"); return(req.CreateResponse(HttpStatusCode.InternalServerError, new { error = message })); } log.Info($""); return(req.CreateResponse(HttpStatusCode.OK, new { vttUrl = vttUrl, ttmlUrl = ttmlUrl, pathUrl = pathUrl, ttmlDocument = ttmlContent, ttmlDocumentWithOffset = ttmlContentTimeCorrected, vttDocument = vttContent, vttDocumentWithOffset = vttContentTimeCorrected })); } }