Beispiel #1
0
        private async static Task DownloadResults(IAzureMediaServicesClient client, string assetName, string resultsFolder)
        {
            ListContainerSasInput parameters        = new ListContainerSasInput();
            AssetContainerSas     assetContainerSas = client.Assets.ListContainerSas(
                resourceGroupName,
                accountName,
                assetName,
                permissions: AssetContainerPermission.Read,
                expiryTime: DateTime.UtcNow.AddHours(1).ToUniversalTime()
                );

            Uri containerSasUrl          = new Uri(assetContainerSas.AssetContainerSasUrls.FirstOrDefault());
            CloudBlobContainer container = new CloudBlobContainer(containerSasUrl);

            string directory = Path.Combine(resultsFolder, assetName);

            Directory.CreateDirectory(directory);

            Console.WriteLine("Downloading results to {0}.", directory);

            var blobs = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, 200, null, null, null).Result;

            foreach (var blobItem in blobs.Results)
            {
                if (blobItem is CloudBlockBlob)
                {
                    CloudBlockBlob blob     = blobItem as CloudBlockBlob;
                    string         filename = Path.Combine(directory, blob.Name);

                    await blob.DownloadToFileAsync(filename, FileMode.Create);
                }
            }

            Console.WriteLine("Download complete.");
        }
Beispiel #2
0
        private static async Task <Asset> CreateInputAsset(IAzureMediaServicesClient client, string assetName, string fileToUpload)
        {
            Console.WriteLine("Creating Input Asset");
            Asset asset = client.Assets.CreateOrUpdate(resourceGroupName, accountName, assetName, new Asset());



            ListContainerSasInput input = new ListContainerSasInput()
            {
                Permissions = AssetContainerPermission.ReadWrite,
                ExpiryTime  = DateTime.Now.AddHours(2).ToUniversalTime()
            };

            var response = client.Assets.ListContainerSasAsync(resourceGroupName, accountName, assetName, input.Permissions, input.ExpiryTime).Result;

            string uploadSasUrl = response.AssetContainerSasUrls.First();

            string filename = Path.GetFileName(fileToUpload);

            Console.WriteLine("Uploading file: {0}", filename);

            var sasUri = new Uri(uploadSasUrl);
            CloudBlobContainer container = new CloudBlobContainer(sasUri);
            var blob = container.GetBlockBlobReference(filename);

            blob.Properties.ContentType = "video/mp4";
            Console.WriteLine("Uploading File to container: {0}", sasUri);
            await blob.UploadFromFileAsync(fileToUpload);

            return(asset);
        }
Beispiel #3
0
        private async Task <string> GetVisualModerationJsonFile(IAzureMediaServicesClient client, string resourceGroupName, string accountName, string assetName)
        {
            ListContainerSasInput parameters        = new ListContainerSasInput();
            AssetContainerSas     assetContainerSas = client.Assets.ListContainerSas(resourceGroupName, accountName, assetName, permissions: AssetContainerPermission.Read, expiryTime: DateTime.UtcNow.AddHours(1).ToUniversalTime());

            Uri containerSasUrl          = new Uri(assetContainerSas.AssetContainerSasUrls.FirstOrDefault());
            CloudBlobContainer container = new CloudBlobContainer(containerSasUrl);

            var blobs = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, 200, null, null, null).Result;

            string jsonString = null;

            foreach (var blobItem in blobs.Results)
            {
                if (blobItem is CloudBlockBlob)
                {
                    CloudBlockBlob blob = blobItem as CloudBlockBlob;
                    if (blob.Name == "contentmoderation.json")
                    {
                        jsonString = await blob.DownloadTextAsync();
                    }
                }
            }
            return(jsonString);
        }
        /// <summary>
        /// Gets an Blob storage container from an asset as an asynchronous operation.
        /// </summary>
        /// <param name="assetName">Name of the asset.</param>
        /// <returns>A task that represents the asynchronous operation with a result
        /// that contains the SAS URI</returns>
        public async Task <Uri> GetAssetContainerAsync(string assetName)
        {
            ListContainerSasInput input = new ListContainerSasInput()
            {
                Permissions = AssetContainerPermission.ReadWrite,
                ExpiryTime  = DateTime.Now.AddHours(1).ToUniversalTime()
            };

            var response = await this.Client.Assets.ListContainerSasAsync(
                this.Options.ResourceGroup,
                this.Options.AccountName,
                assetName,
                input.Permissions,
                input.ExpiryTime).ConfigureAwait(false);

            string uploadSasUrl = response.AssetContainerSasUrls.First();

            return(new Uri(uploadSasUrl));
        }
        public static async Task DoGenerateClientManifestForAllAssetsAsync(AMSClientV3 amsClient, MyDelegate TextBoxLogWriteLine)
        {
            bool cancel = false;

            if (MessageBox.Show("The tool will list the published assets and will create a client manifest when needed.", "Client manifest creation", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) != DialogResult.OK)
            {
                return;
            }


            ListContainerSasInput input = new ListContainerSasInput()
            {
                Permissions = AssetContainerPermission.ReadWriteDelete,
                ExpiryTime  = DateTime.Now.AddHours(2).ToUniversalTime()
            };
            await amsClient.RefreshTokenIfNeededAsync();


            // Get a list of all of the locators and enumerate through them a page at a time.
            IPage <StreamingLocator> firstPage = await amsClient.AMSclient.StreamingLocators.ListAsync(amsClient.credentialsEntry.ResourceGroup, amsClient.credentialsEntry.AccountName);

            IPage <StreamingLocator> currentPage = firstPage;

            do
            {
                foreach (StreamingLocator locator in currentPage)
                {
                    TextBoxLogWriteLine("Inspecting locator {0}...", locator.Name, false);

                    // Get the asset associated with the locator.
                    Asset asset = amsClient.AMSclient.Assets.Get(amsClient.credentialsEntry.ResourceGroup, amsClient.credentialsEntry.AccountName, locator.AssetName);

                    AssetContainerSas response;
                    try
                    {
                        response = await amsClient.AMSclient.Assets.ListContainerSasAsync(amsClient.credentialsEntry.ResourceGroup, amsClient.credentialsEntry.AccountName, asset.Name, input.Permissions, input.ExpiryTime);
                    }
                    catch (Exception ex)
                    {
                        TextBoxLogWriteLine("Error when listing blobs of asset '{0}'.", asset.Name, true); // Warning
                        TextBoxLogWriteLine(Program.GetErrorMessage(ex), string.Empty, true);              // Warning

                        //MessageBox.Show(Program.GetErrorMessage(ex), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    string             uploadSasUrl     = response.AssetContainerSasUrls.First();
                    Uri                sasUri           = new Uri(uploadSasUrl);
                    CloudBlobContainer storageContainer = new CloudBlobContainer(sasUri);

                    // Get a manifest file list from the Storage container.
                    List <string> fileList = GetFilesListFromStorage(storageContainer);

                    string ismcFileName        = fileList.Where(a => a.ToLower().Contains(".ismc")).FirstOrDefault();
                    string ismManifestFileName = fileList.Where(a => a.ToLower().EndsWith(".ism")).FirstOrDefault();
                    // If there is no .ism then there's no reason to continue.  If there's no .ismc we need to add it.
                    if (ismManifestFileName != null && ismcFileName == null)
                    {
                        DialogResult dialog = MessageBox.Show($"Asset {asset.Name} it does not have an ISMC file. Create one ?", "Client manifest creation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                        if (dialog == DialogResult.Yes)
                        {
                            TextBoxLogWriteLine("Asset {0} : it does not have an ISMC file.", asset.Name, false);

                            // let's try to read client manifest
                            XDocument manifest = null;
                            try
                            {
                                manifest = await AssetInfo.TryToGetClientManifestContentUsingStreamingLocatorAsync(asset, amsClient, locator.Name);
                            }
                            catch (Exception ex)
                            {
                                TextBoxLogWriteLine("Error when trying to read client manifest for asset '{0}'.", asset.Name, true); // Warning
                                TextBoxLogWriteLine(Program.GetErrorMessage(ex), string.Empty, true);                                // Warning
                                return;
                            }

                            string ismcContentXml = manifest.ToString();
                            if (ismcContentXml.Length == 0)
                            {
                                TextBoxLogWriteLine("Asset {0} : client manifest is empty.", asset.Name, true); // Warning

                                //error state, skip this asset
                                continue;
                            }
                            if (ismcContentXml.IndexOf("<Protection>") > 0)
                            {
                                TextBoxLogWriteLine("Asset {0} : content is encrypted. Removing the protection header from the client manifest.", asset.Name, false);
                                //remove DRM from the ISCM manifest
                                ismcContentXml = XmlManifestUtils.RemoveXmlNode(ismcContentXml);
                            }
                            string         newIsmcFileName = ismManifestFileName.Substring(0, ismManifestFileName.IndexOf(".")) + ".ismc";
                            CloudBlockBlob ismcBlob        = WriteStringToBlob(ismcContentXml, newIsmcFileName, storageContainer);
                            TextBoxLogWriteLine("Asset {0} : client manifest created.", asset.Name, false);

                            // Download the ISM so that we can modify it to include the ISMC file link.
                            string ismXmlContent = GetFileXmlFromStorage(storageContainer, ismManifestFileName);
                            ismXmlContent = XmlManifestUtils.AddIsmcToIsm(ismXmlContent, newIsmcFileName);
                            WriteStringToBlob(ismXmlContent, ismManifestFileName, storageContainer);
                            TextBoxLogWriteLine("Asset {0} : server manifest updated.", asset.Name, false);

                            // update the ism to point to the ismc (download, modify, delete original, upload new)
                        }
                        else if (dialog == DialogResult.Cancel)
                        {
                            cancel = true;
                            break;
                        }
                    }
                }

                if (cancel)
                {
                    break;
                }

                // Continue on to the next page of locators.
                try
                {
                    currentPage = amsClient.AMSclient.StreamingLocators.ListNext(currentPage.NextPageLink);
                }
                catch (Exception)
                {
                    // we'll get here at the end of the page when the page is empty.  This is okay.
                }
            } while (currentPage.NextPageLink != null);
            MessageBox.Show("Locator listing is complete.", "Client manifest creation", MessageBoxButtons.OK, MessageBoxIcon.Information);
            TextBoxLogWriteLine("Locator listing is complete.", string.Empty, false);
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var assetName = (string)data.assetName;

            if (assetName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Error - please pass assetName in the JSON"));
            }

            // Azure region management
            var azureRegions = new List <string>();

            if ((string)data.azureRegion != null)
            {
                azureRegions = ((string)data.azureRegion).Split(',').ToList();
            }
            else
            {
                azureRegions.Add((string)null);
            }

            CopyStatus copyStatus = CopyStatus.Success;


            foreach (var region in azureRegions)
            {
                ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                         .SetBasePath(Directory.GetCurrentDirectory())
                                                         .AddEnvironmentVariables()
                                                         .Build(),
                                                         region
                                                         );

                MediaServicesHelpers.LogInformation(log, "config loaded.", region);
                MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, region);

                var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

                // 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;

                MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, region);

                try
                {
                    var asset = client.Assets.Get(config.ResourceGroup, config.AccountName, assetName);

                    // Access to container
                    ListContainerSasInput input = new ListContainerSasInput()
                    {
                        Permissions = AssetContainerPermission.ReadWrite,
                        ExpiryTime  = DateTime.Now.AddHours(6).ToUniversalTime()
                    };

                    var responseListSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);

                    string uploadSasUrl             = responseListSas.AssetContainerSasUrls.First();
                    var    sasUri                   = new Uri(uploadSasUrl);
                    var    destinationBlobContainer = new CloudBlobContainer(sasUri);

                    List <IListBlobItem>  blobsresult       = new List <IListBlobItem>();
                    BlobContinuationToken continuationToken = null;
                    do
                    {
                        var responseList = await destinationBlobContainer.ListBlobsSegmentedAsync(null, true, BlobListingDetails.Metadata, null, continuationToken, null, null);

                        continuationToken = responseList.ContinuationToken;
                        blobsresult.AddRange(responseList.Results);
                    }while (continuationToken != null);

                    foreach (var dest in blobsresult)
                    {
                        var destBlob = dest as CloudBlob;
                        await destBlob.FetchAttributesAsync();

                        if (destBlob.CopyState.Status == CopyStatus.Aborted || destBlob.CopyState.Status == CopyStatus.Failed)

                        {
                            // Log the copy status description for diagnostics and restart copy
                            await destBlob.StartCopyAsync(destBlob.CopyState.Source);

                            copyStatus = CopyStatus.Pending;
                        }

                        else if (destBlob.CopyState.Status == CopyStatus.Pending)
                        {
                            // We need to continue waiting for this pending copy
                            // However, let us log copy state for diagnostics
                            copyStatus = CopyStatus.Pending;
                        }

                        // else we completed this pending copy
                    }
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex));
                }
            }

            var response = new JObject
            {
                { "success", true },
                { "copyStatus", copyStatus.ToString() },
                { "isRunning", (copyStatus == CopyStatus.Pending) },
                { "isSuccessful", (copyStatus == CopyStatus.Success) },

                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }
        public static async Task <AssetEntry> GenerateAssetInformation(ConfigWrapper config,
                                                                       IAzureMediaServicesClient client, Asset asset, VodSemaphore semaphore, string contentId = null, string region = null)
        {
            var assetEntry = new AssetEntry()
            {
                AMSAccountName          = config.AccountName,
                Region                  = config.Region,
                ResourceGroup           = config.ResourceGroup,
                AssetStorageAccountName = asset?.StorageAccountName,
                AssetName               = asset.Name,
                Urn               = semaphore?.Urn,
                Semaphore         = semaphore,
                StreamingLocators = new List <StreamingLocatorEntry>(),
                CreatedTime       = asset.Created.ToUniversalTime().ToString(AssetEntry.DateFormat),
                ContentId         = contentId,
            };

            var             urls = new List <OutputUrl>();
            string          streamingPolicyName = null;
            StreamingPolicy streamingPolicy     = null;

            var streamingLocatorsNames = client.Assets.ListStreamingLocators(config.ResourceGroup, config.AccountName, asset.Name).StreamingLocators.Select(l => l.Name);

            foreach (var locatorName in streamingLocatorsNames)
            {
                string           cenckeyId        = null;
                string           cbcskeyId        = null;
                StreamingLocator streamingLocator = null;

                if (locatorName != null)
                {
                    streamingLocator = client.StreamingLocators.Get(config.ResourceGroup,
                                                                    config.AccountName, locatorName);
                    if (streamingLocator != null)
                    {
                        streamingPolicyName = streamingLocator.StreamingPolicyName;

                        if (streamingLocator.ContentKeys
                            .Where(k => k.LabelReferenceInStreamingPolicy == IrdetoHelpers.labelCenc)
                            .FirstOrDefault() != null && streamingLocator.ContentKeys
                            .Where(k => k.LabelReferenceInStreamingPolicy == IrdetoHelpers.labelCbcs)
                            .FirstOrDefault() != null)
                        {
                            cenckeyId = streamingLocator.ContentKeys
                                        .Where(k => k.LabelReferenceInStreamingPolicy == IrdetoHelpers.labelCenc)
                                        .FirstOrDefault().Id.ToString();
                            cbcskeyId = streamingLocator.ContentKeys
                                        .Where(k => k.LabelReferenceInStreamingPolicy == IrdetoHelpers.labelCbcs)
                                        .FirstOrDefault().Id.ToString();
                        }


                        // let's get the manifest name
                        string manifestName        = null;
                        List <IListBlobItem> blobs = new List <IListBlobItem>();
                        try
                        {
                            ListContainerSasInput input = new ListContainerSasInput()
                            {
                                Permissions = AssetContainerPermission.Read,
                                ExpiryTime  = DateTime.Now.AddHours(2).ToUniversalTime()
                            };

                            var    responseListSas = client.Assets.ListContainerSas(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);
                            string uploadSasUrl    = responseListSas.AssetContainerSasUrls.First();

                            var sasUri    = new Uri(uploadSasUrl);
                            var container = new CloudBlobContainer(sasUri);

                            BlobContinuationToken continuationToken = null;
                            do
                            {
                                var response = await container.ListBlobsSegmentedAsync(continuationToken);

                                continuationToken = response.ContinuationToken;
                                blobs.AddRange(response.Results);
                            }while (continuationToken != null);

                            // let's take the first manifest file. It should exist
                            manifestName = blobs.Where(b => (b.GetType() == typeof(CloudBlockBlob))).Select(b => (CloudBlockBlob)b).Where(b => b.Name.ToLower().EndsWith(".ism")).FirstOrDefault().Name;
                        }
                        catch
                        {
                        }
                        if (manifestName != null) // there is a manifest
                        {
                            urls = MediaServicesHelpers.GetUrls(config, client, streamingLocator, manifestName, true, true, true, true, true);
                        }
                        else // no manifest
                        {
                            urls = MediaServicesHelpers.GetDownloadUrls(config, client, streamingLocator, blobs);
                        }
                    }
                }

                if (streamingPolicyName != null)
                {
                    streamingPolicy = client.StreamingPolicies.Get(config.ResourceGroup, config.AccountName,
                                                                   streamingPolicyName);
                }

                var drmlist = new List <Drm>();
                if (streamingPolicy != null)
                {
                    if (streamingPolicy.CommonEncryptionCbcs != null)
                    {
                        var enProt =
                            MediaServicesHelpers.ReturnOutputProtocolsListCbcs(streamingPolicy
                                                                               .CommonEncryptionCbcs.EnabledProtocols);
                        drmlist.Add(new Drm
                        {
                            Type       = "FairPlay",
                            LicenseUrl =
                                streamingPolicy?.CommonEncryptionCbcs?.Drm.FairPlay
                                .CustomLicenseAcquisitionUrlTemplate.Replace("{ContentKeyId}", cbcskeyId).Replace("{AlternativeMediaId}", streamingLocator.AlternativeMediaId),
                            Protocols      = enProt,
                            CertificateUrl = config.IrdetoFairPlayCertificateUrl
                        });
                    }

                    if (streamingPolicy.CommonEncryptionCenc != null)
                    {
                        var enProtW =
                            MediaServicesHelpers.ReturnOutputProtocolsListCencWidevine(streamingPolicy
                                                                                       .CommonEncryptionCbcs.EnabledProtocols);
                        var enProtP =
                            MediaServicesHelpers.ReturnOutputProtocolsListCencPlayReady(streamingPolicy
                                                                                        .CommonEncryptionCbcs.EnabledProtocols);

                        drmlist.Add(new Drm
                        {
                            Type       = "PlayReady",
                            LicenseUrl = streamingPolicy?.CommonEncryptionCenc?.Drm.PlayReady
                                         .CustomLicenseAcquisitionUrlTemplate.Replace("{AlternativeMediaId}", streamingLocator.AlternativeMediaId),
                            Protocols = enProtP
                        });
                        drmlist.Add(new Drm
                        {
                            Type       = "Widevine",
                            LicenseUrl = streamingPolicy?.CommonEncryptionCenc?.Drm.Widevine
                                         .CustomLicenseAcquisitionUrlTemplate.Replace("{AlternativeMediaId}", streamingLocator.AlternativeMediaId),
                            Protocols = enProtW
                        });
                    }
                }

                var StreamingLocatorInfo = new StreamingLocatorEntry
                {
                    StreamingLocatorName = locatorName,
                    StreamingPolicyName  = streamingPolicyName,
                    CencKeyId            = cenckeyId,
                    CbcsKeyId            = cbcskeyId,
                    Drm  = drmlist,
                    Urls = urls.Select(url => new UrlEntry {
                        Protocol = url.Protocol.ToString(), Url = url.Url
                    })
                           .ToList()
                };

                assetEntry.StreamingLocators.Add(StreamingLocatorInfo);
            }

            return(assetEntry);
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var           prefixAssetName = (string)data.prefixAssetName ?? "asset-";
            var           assetName       = (string)data.assetName ?? prefixAssetName + Guid.NewGuid().ToString().Substring(0, 13);
            List <string> containers      = new List <string>();
            List <string> containerPaths  = new List <string>();

            // Azure region management
            var azureRegions = new List <string>();

            if ((string)data.azureRegion != null)
            {
                azureRegions = ((string)data.azureRegion).Split(',').ToList();
            }
            else
            {
                azureRegions.Add((string)null);
            }


            foreach (var region in azureRegions)
            {
                ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                         .SetBasePath(Directory.GetCurrentDirectory())
                                                         .AddEnvironmentVariables()
                                                         .Build(),
                                                         region
                                                         );

                MediaServicesHelpers.LogInformation(log, "config loaded.", region);
                MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, region);

                var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

                // 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;

                MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, region);

                string storageName = (data.baseStorageName != null) ? (string)data.baseStorageName + config.AzureRegionCode : null;

                Asset asset = new Asset()
                {
                    StorageAccountName = storageName, AlternateId = data.alternateId, Description = data.description
                };

                try
                {
                    asset = client.Assets.CreateOrUpdate(config.ResourceGroup, config.AccountName, assetName, asset);
                    asset = client.Assets.Get(config.ResourceGroup, config.AccountName, assetName);

                    // Access to container
                    ListContainerSasInput input = new ListContainerSasInput()
                    {
                        Permissions = AssetContainerPermission.Read,
                        ExpiryTime  = DateTime.Now.AddMinutes(5).ToUniversalTime()
                    };

                    var responseListSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);

                    string uploadSasUrl = responseListSas.AssetContainerSasUrls.First();
                    var    sasUri       = new Uri(uploadSasUrl);
                    var    container    = new CloudBlobContainer(sasUri);

                    containerPaths.Add(container.Uri.ToString());
                    containers.Add(asset.Container);
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex));
                }
            }

            var response = new JObject
            {
                { "success", true },
                { "assetName", assetName },
                { "containerPath", new JArray(containerPaths) },
                { "container", new JArray(containers) },
                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var generalOutputInfos = new List <GeneralOutputInfo>();

            var assetName = (string)data.assetName;

            if (assetName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Error - please pass assetName in the JSON"));
            }

            var fileName = (string)data.fileName;
            ManifestGenerated smildata = null;

            VodSemaphore semaphore = null;

            if (data.semaphore != null)
            {
                semaphore = VodSemaphore.FromJson((string)data.semaphore);
            }

            // Azure region management
            var azureRegions = new List <string>();

            if ((string)data.azureRegion != null)
            {
                azureRegions = ((string)data.azureRegion).Split(',').ToList();
            }
            else
            {
                azureRegions.Add((string)null);
            }


            foreach (var region in azureRegions)
            {
                ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                         .SetBasePath(Directory.GetCurrentDirectory())
                                                         .AddEnvironmentVariables()
                                                         .Build(),
                                                         region
                                                         );

                MediaServicesHelpers.LogInformation(log, "config loaded.", region);
                MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, region);

                var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

                // 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;

                MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, region);
                var asset = client.Assets.Get(config.ResourceGroup, config.AccountName, assetName);

                if (asset == null)
                {
                    throw new Exception($"Asset {asset}  does not exist.");
                }

                // Access to container
                ListContainerSasInput input = new ListContainerSasInput()
                {
                    Permissions = AssetContainerPermission.ReadWriteDelete,
                    ExpiryTime  = DateTime.Now.AddHours(2).ToUniversalTime()
                };

                var responseListSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);

                string uploadSasUrl = responseListSas.AssetContainerSasUrls.First();

                var sasUri    = new Uri(uploadSasUrl);
                var container = new CloudBlobContainer(sasUri);

                // Manifest generate
                smildata = (semaphore == null) ? await ManifestHelpers.LoadAndUpdateManifestTemplate(asset, container, execContext, fileName)
                                                : await ManifestHelpers.LoadAndUpdateManifestTemplateUsingSemaphore(semaphore, execContext, fileName);

                // if not file name passed, then we use the one generated based on mp4 files names
                if (fileName == null)
                {
                    fileName = smildata.FileName;
                }

                var blob = container.GetBlockBlobReference(fileName);

                using (Stream s = ManifestHelpers.GenerateStreamFromString(smildata.Content))
                {
                    await blob.UploadFromStreamAsync(s);
                }
            }

            var response = new JObject
            {
                { "success", true },
                { "fileName", fileName },
                { "manifestContent", smildata.Content },
                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var assetName = (string)data.assetName;

            if (assetName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Error - please pass assetName in the JSON"));
            }

            if (data.fileNames == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass fileNames in the input object"));
            }

            var sourceStorageAccountName = (string)data.sourceStorageAccountName;

            if (sourceStorageAccountName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass sourceStorageAccountName in the input object"));
            }

            var sourceStorageAccountKey = (string)data.sourceStorageAccountKey;

            if (sourceStorageAccountKey == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass sourceStorageAccountKey in the input object"));
            }

            var sourceContainer = (string)data.sourceContainer;

            if (sourceContainer == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass sourceContainer in the input object"));
            }

            bool missingBlob = false;

            List <string> containers     = new List <string>();
            List <string> containerPaths = new List <string>();

            // Azure region management
            var azureRegions = new List <string>();

            if ((string)data.azureRegion != null)
            {
                azureRegions = ((string)data.azureRegion).Split(',').ToList();
            }
            else
            {
                azureRegions.Add((string)null);
            }

            // Setup blob container
            CloudBlobContainer sourceBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(sourceStorageAccountName, sourceStorageAccountKey, (string)data.sourceContainer);

            foreach (var region in azureRegions)
            {
                ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                         .SetBasePath(Directory.GetCurrentDirectory())
                                                         .AddEnvironmentVariables()
                                                         .Build(),
                                                         region
                                                         );

                MediaServicesHelpers.LogInformation(log, "config loaded.", region);
                MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, region);

                var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

                // 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;

                MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, region);

                try
                {
                    var asset = client.Assets.Get(config.ResourceGroup, config.AccountName, assetName);

                    // Access to container
                    ListContainerSasInput input = new ListContainerSasInput()
                    {
                        Permissions = AssetContainerPermission.ReadWrite,
                        ExpiryTime  = DateTime.Now.AddHours(6).ToUniversalTime()
                    };

                    var responseListSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);

                    string uploadSasUrl             = responseListSas.AssetContainerSasUrls.First();
                    var    sasUri                   = new Uri(uploadSasUrl);
                    var    destinationBlobContainer = new CloudBlobContainer(sasUri);
                    containers.Add(asset.Container);


                    if (data.fileNames != null)
                    {
                        int indexFile = 1;
                        foreach (var file in data.fileNames)
                        {
                            string fileName = (string)file;

                            CloudBlob sourceBlob = sourceBlobContainer.GetBlockBlobReference(fileName);

                            if (data.wait != null && (bool)data.wait && (indexFile == 1))
                            {
                                for (int i = 1; i <= 3; i++) // let's wait 3 times 5 seconds (15 seconds)
                                {
                                    if (await sourceBlob.ExistsAsync())
                                    {
                                        break;
                                    }

                                    log.LogInformation("Waiting 5 s...");
                                    System.Threading.Thread.Sleep(5 * 1000);
                                    sourceBlob = sourceBlobContainer.GetBlockBlobReference(fileName);
                                }
                            }

                            if (await sourceBlob.ExistsAsync() && sourceBlob.Properties.Length > 0)
                            {
                                if (data.flattenPath != null && (bool)data.flattenPath)
                                {
                                    fileName = Path.GetFileName(fileName);
                                }

                                CloudBlob destinationBlob = destinationBlobContainer.GetBlockBlobReference(fileName);

                                CopyBlobHelpers.CopyBlobAsync(sourceBlob, destinationBlob);
                            }
                            else
                            {
                                missingBlob = true;
                                log.LogWarning("Missing blob :" + fileName);
                            }
                            indexFile++;
                        }
                    }
                    containers.Add(asset.Container);
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex));
                }
            }

            var response = new JObject
            {
                { "success", true },
                { "assetName", assetName },
                { "container", new JArray(containers) },
                { "missingBlob", missingBlob },
                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var assetName = (string)data.assetName;

            if (assetName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Error - please pass assetName in the JSON"));
            }

            var vttContent = (string)data.vttContent;

            if (vttContent == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass vttContent in the input object"));
            }

            var vttFileName = (string)data.vttFileName;

            if (vttFileName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Please pass vttFileName in the input object"));
            }


            // Azure region management
            var azureRegions = new List <string>();

            if ((string)data.azureRegion != null)
            {
                azureRegions = ((string)data.azureRegion).Split(',').ToList();
            }
            else
            {
                azureRegions.Add((string)null);
            }

            foreach (var region in azureRegions)
            {
                ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                         .SetBasePath(Directory.GetCurrentDirectory())
                                                         .AddEnvironmentVariables()
                                                         .Build(),
                                                         region
                                                         );

                MediaServicesHelpers.LogInformation(log, "config loaded.", region);
                MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, region);

                var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

                // 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;

                MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, region);

                try
                {
                    var asset = client.Assets.Get(config.ResourceGroup, config.AccountName, assetName);

                    // Access to container
                    ListContainerSasInput input = new ListContainerSasInput()
                    {
                        Permissions = AssetContainerPermission.ReadWrite,
                        ExpiryTime  = DateTime.Now.AddHours(6).ToUniversalTime()
                    };

                    var responseListSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, asset.Name, input.Permissions, input.ExpiryTime);

                    string uploadSasUrl             = responseListSas.AssetContainerSasUrls.First();
                    var    sasUri                   = new Uri(uploadSasUrl);
                    var    destinationBlobContainer = new CloudBlobContainer(sasUri);

                    var destinationBlob = destinationBlobContainer.GetBlockBlobReference(vttFileName);

                    // Base 64 decoding
                    byte[] dataVtt       = Convert.FromBase64String(vttContent);
                    string decodedString = Encoding.UTF8.GetString(dataVtt);

                    // Uploading data
                    await destinationBlob.UploadTextAsync(decodedString);
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex));
                }
            }

            var response = new JObject
            {
                { "success", true },
                { "assetName", assetName },
                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext execContext)
        {
            MediaServicesHelpers.LogInformation(log, "C# HTTP trigger function processed a request.");

            dynamic data;

            try
            {
                data = JsonConvert.DeserializeObject(new StreamReader(req.Body).ReadToEnd());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var assetName = (string)data.assetName;

            if (assetName == null)
            {
                return(IrdetoHelpers.ReturnErrorException(log, "Error - please pass assetName in the JSON"));
            }

            List <string> fileNames = new List <string>();

            ConfigWrapper config = new ConfigWrapper(new ConfigurationBuilder()
                                                     .SetBasePath(Directory.GetCurrentDirectory())
                                                     .AddEnvironmentVariables()
                                                     .Build(),
                                                     null
                                                     );

            MediaServicesHelpers.LogInformation(log, "connecting to AMS account : " + config.AccountName, null);

            var client = await MediaServicesHelpers.CreateMediaServicesClientAsync(config);

            // 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;

            MediaServicesHelpers.LogInformation(log, "asset name : " + assetName, null);

            Asset asset = new Asset();

            try
            {
                asset = await client.Assets.GetAsync(config.ResourceGroup, config.AccountName, assetName);

                ListContainerSasInput input = new ListContainerSasInput()
                {
                    Permissions = AssetContainerPermission.Read,
                    ExpiryTime  = DateTime.Now.AddHours(2).ToUniversalTime()
                };

                var responseAssetContSas = await client.Assets.ListContainerSasAsync(config.ResourceGroup, config.AccountName, assetName, input.Permissions, input.ExpiryTime);

                string uploadSasUrl = responseAssetContSas.AssetContainerSasUrls.First();
                Uri    sasUri       = new Uri(uploadSasUrl);
                var    container    = new CloudBlobContainer(sasUri);


                BlobContinuationToken continuationToken = null;
                var blobs = new List <IListBlobItem>();

                do
                {
                    BlobResultSegment segment = await container.ListBlobsSegmentedAsync(null, false, BlobListingDetails.Metadata, null, continuationToken, null, null);

                    blobs.AddRange(segment.Results);

                    foreach (IListBlobItem blob in segment.Results)
                    {
                        if (blob.GetType() == typeof(CloudBlockBlob))
                        {
                            CloudBlockBlob bl = (CloudBlockBlob)blob;
                            fileNames.Add(bl.Name);
                        }
                    }
                    continuationToken = segment.ContinuationToken;
                }while (continuationToken != null);
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            var response = new JObject
            {
                { "success", true },
                { "assetName", assetName },
                { "assetId", asset.AssetId },
                { "fileNames", new JArray(fileNames) },
                { "container", asset.Container },
                { "storageAccountName", asset.StorageAccountName },
                {
                    "operationsVersion",
                    AssemblyName.GetAssemblyName(Assembly.GetExecutingAssembly().Location).Version.ToString()
                }
            };

            return(new OkObjectResult(
                       response
                       ));
        }