/// <summary>
        /// Get or create a custom streaming policy for FairPlay.
        /// </summary>
        /// <param name="client">The Media Services client.</param>
        /// <param name="resourceGroupName">The name of the resource group within the Azure subscription.</param>
        /// <param name="accountName"> The Media Services account name.</param>
        /// <param name="streamingPolicyName">The streaming policy name.</param>
        /// <returns>StreamingPolicy</returns>
        private static async Task <StreamingPolicy> GetOrCreateCustomStreamingPolicyForFairPlay(IAzureMediaServicesClient client,
                                                                                                string resourceGroupName, string accountName, string streamingPolicyName)
        {
            // In Media Services v3, the Get method on entities will return an ErrorResponseException if the resource is not found.
            bool            createPolicy    = false;
            StreamingPolicy streamingPolicy = null;

            try
            {
                streamingPolicy = await client.StreamingPolicies.GetAsync(resourceGroupName, accountName, streamingPolicyName);

                Console.WriteLine($"Warning: The streaming policy named {streamingPolicyName} already exists.");
            }


            catch (ErrorResponseException ex) when(ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                // Content key policy does not exist
                createPolicy = true;
            }

            if (createPolicy)
            {
                streamingPolicy = new StreamingPolicy
                {
                    CommonEncryptionCbcs = new CommonEncryptionCbcs()
                    {
                        Drm = new CbcsDrmConfiguration()
                        {
                            FairPlay = new StreamingPolicyFairPlayConfiguration()
                            {
                                AllowPersistentLicense = true  // this enables offline mode
                            }
                        },
                        EnabledProtocols = new EnabledProtocols()
                        {
                            Hls  = true,
                            Dash = true //Even though DASH under CBCS is not supported for either CSF or CMAF, HLS-CMAF-CBCS uses DASH-CBCS fragments in its HLS playlist
                        },

                        ContentKeys = new StreamingPolicyContentKeys()
                        {
                            //Default key must be specified if keyToTrackMappings is present
                            DefaultKey = new DefaultKey()
                            {
                                Label = "CBCS_DefaultKeyLabel"
                            }
                        }
                    }
                };

                streamingPolicy = await client.StreamingPolicies.CreateAsync(resourceGroupName, accountName, streamingPolicyName, streamingPolicy);
            }

            return(streamingPolicy);
        }
        public void StreamingPolicyComboTest()
        {
            using (MockContext context = this.StartMockContextAndInitializeClients(this.GetType()))
            {
                try
                {
                    CreateMediaServicesAccount();

                    // List StreamingPolicies, which should only contain the predefined policies
                    var policies = MediaClient.StreamingPolicies.List(ResourceGroup, AccountName);
                    Assert.Empty(policies.Where(p => !p.Name.StartsWith("Predefined_")));

                    string policyName = TestUtilities.GenerateName("StreamingPolicy");

                    // Get the StreamingPolicy, which should not exist
                    StreamingPolicy policy = MediaClient.StreamingPolicies.Get(ResourceGroup, AccountName, policyName);
                    Assert.Null(policy);

                    // Create a new StreamingPolicy
                    string defaultContentKeyPolicyName        = null;
                    CommonEncryptionCbcs commonEncryptionCbcs = null;
                    CommonEncryptionCenc commonEncryptionCenc = null;
                    EnvelopeEncryption   envelopeEncryption   = new EnvelopeEncryption(enabledProtocols: new EnabledProtocols(false, false, true, false));
                    NoEncryption         noEncryption         = null;
                    var             input         = new StreamingPolicy(envelopeEncryption: envelopeEncryption);
                    StreamingPolicy createdPolicy = MediaClient.StreamingPolicies.Create(ResourceGroup, AccountName, policyName, input);
                    ValidateStreamingPolicy(createdPolicy, policyName, defaultContentKeyPolicyName, commonEncryptionCbcs, commonEncryptionCenc, envelopeEncryption, noEncryption);

                    // List StreamingPolicies and validate the newly created one shows up
                    policies = MediaClient.StreamingPolicies.List(ResourceGroup, AccountName);
                    policy   = policies.Where(p => !p.Name.StartsWith("Predefined_")).First();
                    ValidateStreamingPolicy(policy, policyName, defaultContentKeyPolicyName, commonEncryptionCbcs, commonEncryptionCenc, envelopeEncryption, noEncryption);

                    // Get the newly created StreamingPolicy
                    policy = MediaClient.StreamingPolicies.Get(ResourceGroup, AccountName, policyName);
                    Assert.NotNull(policy);
                    ValidateStreamingPolicy(policy, policyName, defaultContentKeyPolicyName, commonEncryptionCbcs, commonEncryptionCenc, envelopeEncryption, noEncryption);

                    // Delete the StreamingPolicy
                    MediaClient.StreamingPolicies.Delete(ResourceGroup, AccountName, policyName);

                    // List StreamingPolicies, which should only contain the predefined policies
                    policies = MediaClient.StreamingPolicies.List(ResourceGroup, AccountName);
                    Assert.Empty(policies.Where(p => !p.Name.StartsWith("Predefined_")));

                    // Get the StreamingPolicy, which should not exist
                    policy = MediaClient.StreamingPolicies.Get(ResourceGroup, AccountName, policyName);
                    Assert.Null(policy);
                }
                finally
                {
                    DeleteMediaServicesAccount();
                }
            }
        }
        public static async Task <StreamingPolicy> CreateStreamingPolicyIrdeto(ConfigWrapper config,
                                                                               IAzureMediaServicesClient client, string uniqueness = null)
        {
            if (uniqueness == null)
            {
                uniqueness = Guid.NewGuid().ToString().Substring(0, 13);
            }

            var dash_smooth_protocol = new EnabledProtocols(false, true, false, true);
            var hls_dash_protocol    = new EnabledProtocols(false, true, true, false);
            var cenc_config          = new CencDrmConfiguration(
                new StreamingPolicyPlayReadyConfiguration
            {
                CustomLicenseAcquisitionUrlTemplate = config.IrdetoPlayReadyLAURL
            },
                new StreamingPolicyWidevineConfiguration
            {
                CustomLicenseAcquisitionUrlTemplate = config.IrdetoWidevineLAURL
            }
                );
            var cbcs_config = new CbcsDrmConfiguration(
                new StreamingPolicyFairPlayConfiguration
            {
                CustomLicenseAcquisitionUrlTemplate = config.IrdetoFairPlayLAURL
            }
                );

            var ContentKeysEnc = new StreamingPolicyContentKeys
            {
                DefaultKey = new DefaultKey
                {
                    Label = labelCenc
                }
            };

            var ContentKeysCbcsc = new StreamingPolicyContentKeys
            {
                DefaultKey = new DefaultKey
                {
                    Label = labelCbcs
                }
            };

            var cenc = new CommonEncryptionCenc(dash_smooth_protocol, null, ContentKeysEnc, cenc_config);
            var cbcs = new CommonEncryptionCbcs(hls_dash_protocol, null, ContentKeysCbcsc, cbcs_config);

            var policyName      = uniqueness;
            var streamingPolicy = new StreamingPolicy(Guid.NewGuid().ToString(), policyName, null, DateTime.Now, null,
                                                      null, cenc, cbcs, null);

            streamingPolicy = await client.StreamingPolicies.CreateAsync(config.ResourceGroup, config.AccountName,
                                                                         policyName, streamingPolicy);

            return(streamingPolicy);
        }
        internal static void ValidateStreamingPolicy(
            StreamingPolicy policy,
            string expectedName,
            string expectedDefaultContentKeyPolicyName,
            CommonEncryptionCbcs expectedCommonEncryptionCbcs,
            CommonEncryptionCenc expectedCommonEncryptionCenc,
            EnvelopeEncryption expectedEnvelopeEncryption,
            NoEncryption expectedNoEncryption)
        {
            Assert.Equal(expectedName, policy.Name);
            Assert.Equal(expectedDefaultContentKeyPolicyName, policy.DefaultContentKeyPolicyName);
            Assert.False(string.IsNullOrEmpty(policy.Id));

            if (expectedCommonEncryptionCbcs == null)
            {
                Assert.Null(policy.CommonEncryptionCbcs);
            }
            else
            {
                ValidateEnabledProtocols(expectedCommonEncryptionCbcs.EnabledProtocols, policy.CommonEncryptionCbcs.EnabledProtocols);
            }

            if (expectedCommonEncryptionCenc == null)
            {
                Assert.Null(policy.CommonEncryptionCenc);
            }
            else
            {
                ValidateEnabledProtocols(expectedCommonEncryptionCenc.EnabledProtocols, policy.CommonEncryptionCenc.EnabledProtocols);
            }

            if (expectedEnvelopeEncryption == null)
            {
                Assert.Null(policy.EnvelopeEncryption);
            }
            else
            {
                ValidateEnabledProtocols(expectedEnvelopeEncryption.EnabledProtocols, policy.EnvelopeEncryption.EnabledProtocols);
            }

            if (expectedNoEncryption == null)
            {
                Assert.Null(policy.NoEncryption);
            }
            else
            {
                ValidateEnabledProtocols(expectedNoEncryption.EnabledProtocols, policy.NoEncryption.EnabledProtocols);
            }
        }
        /// <summary>
        /// Creates a StreamingLocator for the specified asset and with the specified streaming policy name.
        /// Once the StreamingLocator is created the output asset is available to clients for playback.
        /// </summary>
        /// <param name="client">The Media Services client.</param>
        /// <param name="resourceGroupName">The name of the resource group within the Azure subscription.</param>
        /// <param name="accountName"> The Media Services account name.</param>
        /// <param name="assetName">The name of the output asset.</param>
        /// <param name="locatorName">The StreamingLocator name (unique in this case).</param>
        /// <returns></returns>
        private static async Task <StreamingLocator> CreateStreamingLocatorAsync(
            IAzureMediaServicesClient client,
            string resourceGroup,
            string accountName,
            string assetName,
            string locatorName,
            string contentPolicyName)
        {
            StreamingLocator locator;

            // Let's check if the locator exists already
            try
            {
                locator = await client.StreamingLocators.GetAsync(resourceGroup, accountName, locatorName);
            }
            catch (ErrorResponseException ex) when(ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                // Name collision! This should not happen in this sample. If it does happen, in order to get the sample to work,
                // let's just go ahead and create a unique name.
                // Note that the returned locatorName can have a different name than the one specified as an input parameter.
                // You may want to update this part to throw an Exception instead, and handle name collisions differently.
                Console.WriteLine("Warning – found an existing Streaming Locator with name = " + locatorName);

                string uniqueness = $"-{Guid.NewGuid():N}";

                locatorName += uniqueness;

                Console.WriteLine("Creating a Streaming Locator with this name instead: " + locatorName);
            }

            StreamingPolicy customStreamingPolicy = await GetOrCreateCustomStreamingPolicyForFairPlay(client, resourceGroup, accountName,
                                                                                                      FairPlayStreamingPolicyName);

            Console.WriteLine("Creating a streaming locator...");
            locator = await client.StreamingLocators.CreateAsync(
                resourceGroup,
                accountName,
                locatorName,
                new StreamingLocator
            {
                AssetName                   = assetName,
                StreamingPolicyName         = customStreamingPolicy.Name, // Custom StreamingPolicy
                DefaultContentKeyPolicyName = contentPolicyName
            });

            return(locator);
        }
示例#6
0
        /// <summary>
        /// Get or create a custom streaming policy for FairPlay.
        /// </summary>
        /// <param name="client">The Media Services client.</param>
        /// <param name="resourceGroupName">The name of the resource group within the Azure subscription.</param>
        /// <param name="accountName"> The Media Services account name.</param>
        /// <param name="streamingPolicyName">The streaming policy name.</param>
        /// <returns>StreamingPolicy</returns>
        private static async Task <StreamingPolicy> GetOrCreateCustomStreamingPloliyForFairPlay(IAzureMediaServicesClient client,
                                                                                                string resourceGroupName, string accountName, string streamingPolicyName)
        {
            StreamingPolicy streamingPolicy = await client.StreamingPolicies.GetAsync(resourceGroupName, accountName, streamingPolicyName);

            if (streamingPolicy == null)
            {
                streamingPolicy = new StreamingPolicy
                {
                    CommonEncryptionCbcs = new CommonEncryptionCbcs()
                    {
                        Drm = new CbcsDrmConfiguration()
                        {
                            FairPlay = new StreamingPolicyFairPlayConfiguration()
                            {
                                AllowPersistentLicense = true  // this enables offline mode
                            }
                        },
                        EnabledProtocols = new EnabledProtocols()
                        {
                            Hls  = true,
                            Dash = true //Even though DASH under CBCS is not supported for either CSF or CMAF, HLS-CMAF-CBCS uses DASH-CBCS fragments in its HLS playlist
                        },

                        ContentKeys = new StreamingPolicyContentKeys()
                        {
                            //Default key must be specified if keyToTrackMappings is present
                            DefaultKey = new DefaultKey()
                            {
                                Label = "CBCS_DefaultKeyLabel"
                            }
                        }
                    }
                };

                streamingPolicy = await client.StreamingPolicies.CreateAsync(resourceGroupName, accountName, streamingPolicyName, streamingPolicy);
            }

            return(streamingPolicy);
        }
示例#7
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log)
        {
            log.LogInformation("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 liveEventName = (string)data.liveEventName;

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

            // default settings
            var eventInfoFromCosmos = new LiveEventSettingsInfo()
            {
                LiveEventName = liveEventName
            };

            // Load config from Cosmos
            try
            {
                var setting = await CosmosHelpers.ReadSettingsDocument(liveEventName);

                eventInfoFromCosmos = setting ?? eventInfoFromCosmos;

                if (setting == null)
                {
                    log.LogWarning("Settings not read from Cosmos.");
                }
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

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

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

            // init default
            var uniquenessAssets = Guid.NewGuid().ToString().Substring(0, 13);

            var streamingLocatorGuid = Guid.NewGuid(); // same locator for the two ouputs if 2 live event namle created
            var uniquenessLocator    = streamingLocatorGuid.ToString().Substring(0, 13);
            var streamingLocatorName = "locator-" + uniquenessLocator;

            string uniquenessPolicyName = Guid.NewGuid().ToString().Substring(0, 13);

            var manifestName = liveEventName.ToLower();

            var useDRM = data.useDRM != null ? (bool)data.useDRM : true;

            if (data.archiveWindowLength != null)
            {
                eventInfoFromCosmos.ArchiveWindowLength = (int)data.archiveWindowLength;
            }

            if (data.inputProtocol != null && ((string)data.inputProtocol).ToUpper() == "RTMP")
            {
                eventInfoFromCosmos.InputProtocol = LiveEventInputProtocol.RTMP;
            }

            if (data.liveEventAutoStart != null)
            {
                eventInfoFromCosmos.AutoStart = (bool)data.liveEventAutoStart;
            }

            if (data.InputACL != null)
            {
                eventInfoFromCosmos.LiveEventInputACL = (List <string>)data.InputACL;
            }

            if (data.PreviewACL != null)
            {
                eventInfoFromCosmos.LiveEventPreviewACL = (List <string>)data.PreviewACL;
            }

            if (data.lowLatency != null)
            {
                eventInfoFromCosmos.LowLatency = (bool)data.lowLatency;
            }

            if (data.useStaticHostname != null)
            {
                eventInfoFromCosmos.UseStaticHostname = (bool)data.useStaticHostname;
            }

            var cencKey = new StreamingLocatorContentKey();
            var cbcsKey = new StreamingLocatorContentKey();

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

                    MediaServicesHelpers.LogInformation(log, "Irdeto call...");

                    cencKey = await IrdetoHelpers.GenerateAndRegisterCENCKeyToIrdeto(liveEventName, config);

                    cbcsKey = await IrdetoHelpers.GenerateAndRegisterCBCSKeyToIrdeto(liveEventName, config);

                    MediaServicesHelpers.LogInformation(log, "Irdeto call done.");
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex, "Irdeto response error"));
                }
            }

            var clientTasks = new List <Task <LiveEventEntry> >();

            foreach (var region in azureRegions)
            {
                var task = Task <LiveEventEntry> .Run(async() =>
                {
                    Asset asset                     = null;
                    LiveEvent liveEvent             = null;
                    LiveOutput liveOutput           = null;
                    StreamingPolicy streamingPolicy = null;
                    string storageName              = null;

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

                    if (eventInfoFromCosmos.BaseStorageName != null)
                    {
                        storageName = eventInfoFromCosmos.BaseStorageName + config.AzureRegionCode;
                    }

                    if (data.storageAccountName != null)
                    {
                        storageName = (string)data.storageAccountName;
                    }

                    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;

                    // LIVE EVENT CREATION
                    MediaServicesHelpers.LogInformation(log, "Live event creation...", region);

                    // let's check that the channel does not exist already
                    liveEvent = await client.LiveEvents.GetAsync(config.ResourceGroup, config.AccountName, liveEventName);
                    if (liveEvent != null)
                    {
                        throw new Exception("Error : live event already exists !");
                    }

                    // IP ACL for preview URL
                    var ipsPreview = new List <IPRange>();
                    if (eventInfoFromCosmos.LiveEventPreviewACL == null ||
                        eventInfoFromCosmos.LiveEventPreviewACL.Count == 0)
                    {
                        MediaServicesHelpers.LogInformation(log, "preview all", region);
                        var ip = new IPRange
                        {
                            Name = "AllowAll", Address = IPAddress.Parse("0.0.0.0").ToString(), SubnetPrefixLength = 0
                        };
                        ipsPreview.Add(ip);
                    }
                    else
                    {
                        foreach (var ipacl in eventInfoFromCosmos.LiveEventPreviewACL)
                        {
                            var ipaclcomp = ipacl.Split('/'); // notation can be "192.168.0.1" or "192.168.0.1/32"
                            var subnet    = ipaclcomp.Count() > 1 ? Convert.ToInt32(ipaclcomp[1]) : 0;
                            var ip        = new IPRange
                            {
                                Name               = "ip",
                                Address            = IPAddress.Parse(ipaclcomp[0]).ToString(),
                                SubnetPrefixLength = subnet
                            };
                            ipsPreview.Add(ip);
                        }
                    }

                    var liveEventPreview = new LiveEventPreview
                    {
                        AccessControl = new LiveEventPreviewAccessControl(new IPAccessControl(ipsPreview))
                    };

                    // IP ACL for input URL
                    var ipsInput = new List <IPRange>();

                    if (eventInfoFromCosmos.LiveEventInputACL == null || eventInfoFromCosmos.LiveEventInputACL.Count == 0)
                    {
                        MediaServicesHelpers.LogInformation(log, "input all", region);
                        var ip = new IPRange
                        {
                            Name = "AllowAll", Address = IPAddress.Parse("0.0.0.0").ToString(), SubnetPrefixLength = 0
                        };
                        ipsInput.Add(ip);
                    }
                    else
                    {
                        foreach (var ipacl in eventInfoFromCosmos.LiveEventInputACL)
                        {
                            var ipaclcomp = ipacl.Split('/'); // notation can be "192.168.0.1" or "192.168.0.1/32"
                            var subnet    = ipaclcomp.Count() > 1 ? Convert.ToInt32(ipaclcomp[1]) : 0;
                            var ip        = new IPRange
                            {
                                Name               = "ip",
                                Address            = IPAddress.Parse(ipaclcomp[0]).ToString(),
                                SubnetPrefixLength = subnet
                            };
                            ipsInput.Add(ip);
                        }
                    }

                    var liveEventInput = new LiveEventInput(
                        eventInfoFromCosmos.InputProtocol,
                        accessControl: new LiveEventInputAccessControl(new IPAccessControl(ipsInput)),
                        accessToken: config.LiveIngestAccessToken
                        );

                    liveEvent = new LiveEvent(
                        name: liveEventName,
                        location: config.Region,
                        description: "",
                        useStaticHostname: eventInfoFromCosmos.UseStaticHostname,
                        encoding: new LiveEventEncoding {
                        EncodingType = LiveEventEncodingType.None
                    },
                        input: liveEventInput,
                        preview: liveEventPreview,
                        streamOptions: new List <StreamOptionsFlag?>
                    {
                        // Set this to Default or Low Latency
                        eventInfoFromCosmos.LowLatency?StreamOptionsFlag.LowLatency: StreamOptionsFlag.Default
                    }
                        );


                    liveEvent = await client.LiveEvents.CreateAsync(config.ResourceGroup, config.AccountName, liveEventName,
                                                                    liveEvent, eventInfoFromCosmos.AutoStart);
                    MediaServicesHelpers.LogInformation(log, "Live event created.", region);


                    if (useDRM)
                    {
                        MediaServicesHelpers.LogInformation(log, "Trying to read streaming policy from Cosmos.", region);
                        string streamingPolicyName = null;
                        // Load streaming policy info from Cosmos
                        try
                        {
                            var info = await CosmosHelpers.ReadStreamingPolicyDocument(new StreamingPolicyInfo(false)
                            {
                                AMSAccountName = config.AccountName
                            });

                            if (info == null)
                            {
                                log.LogWarning("Streaming policy not read from Cosmos.");
                            }
                            else
                            {
                                streamingPolicyName = info.StreamingPolicyName;
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("Error reading Cosmos DB", ex);
                        }


                        // STREAMING POLICY CREATION
                        if (streamingPolicyName == null) // not found in Cosmos let's create a new one
                        {
                            MediaServicesHelpers.LogInformation(log, "Creating streaming policy.", region);
                            try
                            {
                                streamingPolicy = await IrdetoHelpers.CreateStreamingPolicyIrdeto(config, client, uniquenessPolicyName);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Streaming policy creation error", ex);
                            }

                            try
                            {
                                if (!await CosmosHelpers.CreateOrUpdatePolicyDocument(new StreamingPolicyInfo(false)
                                {
                                    AMSAccountName = config.AccountName,
                                    StreamingPolicyName = streamingPolicy.Name
                                }))
                                {
                                    log.LogWarning("Cosmos access not configured or error.");
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Streaming policy write error to Cosmos", ex);
                            }
                        }
                        else
                        {
                            MediaServicesHelpers.LogInformation(log, "Getting streaming policy in AMS.", region);
                            try
                            {
                                streamingPolicy = await client.StreamingPolicies.GetAsync(config.ResourceGroup, config.AccountName, streamingPolicyName);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Error when getting streaming policy " + streamingPolicy, ex);
                            }
                        }
                    }

                    // LIVE OUTPUT CREATION
                    MediaServicesHelpers.LogInformation(log, "Live output creation...", region);

                    try
                    {
                        MediaServicesHelpers.LogInformation(log, "Asset creation...", region);

                        asset = await client.Assets.CreateOrUpdateAsync(config.ResourceGroup, config.AccountName,
                                                                        "asset-" + uniquenessAssets,
                                                                        new Asset(storageAccountName: storageName));

                        Hls hlsParam = null;

                        liveOutput = new LiveOutput(asset.Name, TimeSpan.FromMinutes(eventInfoFromCosmos.ArchiveWindowLength),
                                                    null, "output-" + uniquenessAssets, null, null, manifestName,
                                                    hlsParam); //we put the streaming locator in description
                        MediaServicesHelpers.LogInformation(log, "await task...", region);

                        MediaServicesHelpers.LogInformation(log, "create live output...", region);
                        await client.LiveOutputs.CreateAsync(config.ResourceGroup, config.AccountName, liveEventName,
                                                             liveOutput.Name, liveOutput);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("live output creation error", ex);
                    }


                    try
                    {
                        // let's get the asset
                        // in v3, asset name = asset if in v2 (without prefix)
                        MediaServicesHelpers.LogInformation(log, "Asset configuration.", region);

                        StreamingLocator locator = null;
                        if (useDRM)
                        {
                            locator = await IrdetoHelpers.SetupDRMAndCreateLocatorWithNewKeys(config, streamingPolicy.Name,
                                                                                              streamingLocatorName, client, asset, cencKey, cbcsKey, streamingLocatorGuid, liveEventName);
                        }
                        else // no DRM
                        {
                            locator = await IrdetoHelpers.CreateClearLocator(config, streamingLocatorName, client, asset, streamingLocatorGuid);
                        }

                        MediaServicesHelpers.LogInformation(log, "locator : " + locator.Name, region);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("locator creation error", ex);
                    }

                    // let's build info for the live event and output

                    var generalOutputInfo =
                        GenerateInfoHelpers.GenerateOutputInformation(config, client, new List <LiveEvent> {
                        liveEvent
                    });

                    if (!await CosmosHelpers.CreateOrUpdateGeneralInfoDocument(generalOutputInfo.LiveEvents[0]))
                    {
                        log.LogWarning("Cosmos access not configured.");
                    }

                    return(generalOutputInfo.LiveEvents[0]);
                });

                clientTasks.Add(task);
            }

            try
            {
                Task.WaitAll(clientTasks.ToArray());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            return(new OkObjectResult(
                       JsonConvert.SerializeObject(new GeneralOutputInfo {
                Success = true, LiveEvents = clientTasks.Select(i => i.Result).ToList()
            }, Formatting.Indented)
                       ));
        }
示例#8
0
        /// <summary>
        /// Create a Streaming Policy
        /// </summary>
        /// <remarks>
        /// Create a Streaming Policy in the Media Services account
        /// </remarks>
        /// <param name='resourceGroupName'>
        /// The name of the resource group within the Azure subscription.
        /// </param>
        /// <param name='accountName'>
        /// The Media Services account name.
        /// </param>
        /// <param name='streamingPolicyName'>
        /// The Streaming Policy name.
        /// </param>
        /// <param name='parameters'>
        /// The request parameters
        /// </param>
        /// <param name='customHeaders'>
        /// Headers that will be added to request.
        /// </param>
        /// <param name='cancellationToken'>
        /// The cancellation token.
        /// </param>
        /// <exception cref="ApiErrorException">
        /// Thrown when the operation returned an invalid status code
        /// </exception>
        /// <exception cref="SerializationException">
        /// Thrown when unable to deserialize the response
        /// </exception>
        /// <exception cref="ValidationException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown when a required parameter is null
        /// </exception>
        /// <return>
        /// A response object containing the response body and response headers.
        /// </return>
        public async Task <AzureOperationResponse <StreamingPolicy> > CreateWithHttpMessagesAsync(string resourceGroupName, string accountName, string streamingPolicyName, StreamingPolicy parameters, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (Client.SubscriptionId == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "this.Client.SubscriptionId");
            }
            if (resourceGroupName == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "resourceGroupName");
            }
            if (accountName == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "accountName");
            }
            if (streamingPolicyName == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "streamingPolicyName");
            }
            if (parameters == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "parameters");
            }
            if (parameters != null)
            {
                parameters.Validate();
            }
            string apiVersion = "2020-05-01";
            // Tracing
            bool   _shouldTrace  = ServiceClientTracing.IsEnabled;
            string _invocationId = null;

            if (_shouldTrace)
            {
                _invocationId = ServiceClientTracing.NextInvocationId.ToString();
                Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
                tracingParameters.Add("resourceGroupName", resourceGroupName);
                tracingParameters.Add("accountName", accountName);
                tracingParameters.Add("streamingPolicyName", streamingPolicyName);
                tracingParameters.Add("parameters", parameters);
                tracingParameters.Add("apiVersion", apiVersion);
                tracingParameters.Add("cancellationToken", cancellationToken);
                ServiceClientTracing.Enter(_invocationId, this, "Create", tracingParameters);
            }
            // Construct URL
            var _baseUrl = Client.BaseUri.AbsoluteUri;
            var _url     = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Media/mediaServices/{accountName}/streamingPolicies/{streamingPolicyName}").ToString();

            _url = _url.Replace("{subscriptionId}", System.Uri.EscapeDataString(Client.SubscriptionId));
            _url = _url.Replace("{resourceGroupName}", System.Uri.EscapeDataString(resourceGroupName));
            _url = _url.Replace("{accountName}", System.Uri.EscapeDataString(accountName));
            _url = _url.Replace("{streamingPolicyName}", System.Uri.EscapeDataString(streamingPolicyName));
            List <string> _queryParameters = new List <string>();

            if (apiVersion != null)
            {
                _queryParameters.Add(string.Format("api-version={0}", System.Uri.EscapeDataString(apiVersion)));
            }
            if (_queryParameters.Count > 0)
            {
                _url += (_url.Contains("?") ? "&" : "?") + string.Join("&", _queryParameters);
            }
            // Create HTTP transport objects
            var _httpRequest = new HttpRequestMessage();
            HttpResponseMessage _httpResponse = null;

            _httpRequest.Method     = new HttpMethod("PUT");
            _httpRequest.RequestUri = new System.Uri(_url);
            // Set Headers
            if (Client.GenerateClientRequestId != null && Client.GenerateClientRequestId.Value)
            {
                _httpRequest.Headers.TryAddWithoutValidation("x-ms-client-request-id", System.Guid.NewGuid().ToString());
            }
            if (Client.AcceptLanguage != null)
            {
                if (_httpRequest.Headers.Contains("accept-language"))
                {
                    _httpRequest.Headers.Remove("accept-language");
                }
                _httpRequest.Headers.TryAddWithoutValidation("accept-language", Client.AcceptLanguage);
            }


            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    if (_httpRequest.Headers.Contains(_header.Key))
                    {
                        _httpRequest.Headers.Remove(_header.Key);
                    }
                    _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
                }
            }

            // Serialize Request
            string _requestContent = null;

            if (parameters != null)
            {
                _requestContent      = Rest.Serialization.SafeJsonConvert.SerializeObject(parameters, Client.SerializationSettings);
                _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8);
                _httpRequest.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json; charset=utf-8");
            }
            // Set Credentials
            if (Client.Credentials != null)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
            }
            // Send Request
            if (_shouldTrace)
            {
                ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
            }
            cancellationToken.ThrowIfCancellationRequested();
            _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

            if (_shouldTrace)
            {
                ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
            }
            HttpStatusCode _statusCode = _httpResponse.StatusCode;

            cancellationToken.ThrowIfCancellationRequested();
            string _responseContent = null;

            if ((int)_statusCode != 201)
            {
                var ex = new ApiErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
                try
                {
                    _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

                    ApiError _errorBody = Rest.Serialization.SafeJsonConvert.DeserializeObject <ApiError>(_responseContent, Client.DeserializationSettings);
                    if (_errorBody != null)
                    {
                        ex.Body = _errorBody;
                    }
                }
                catch (JsonException)
                {
                    // Ignore the exception
                }
                ex.Request  = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
                ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(_invocationId, ex);
                }
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw ex;
            }
            // Create Result
            var _result = new AzureOperationResponse <StreamingPolicy>();

            _result.Request  = _httpRequest;
            _result.Response = _httpResponse;
            if (_httpResponse.Headers.Contains("x-ms-request-id"))
            {
                _result.RequestId = _httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault();
            }
            // Deserialize Response
            if ((int)_statusCode == 201)
            {
                _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

                try
                {
                    _result.Body = Rest.Serialization.SafeJsonConvert.DeserializeObject <StreamingPolicy>(_responseContent, Client.DeserializationSettings);
                }
                catch (JsonException ex)
                {
                    _httpRequest.Dispose();
                    if (_httpResponse != null)
                    {
                        _httpResponse.Dispose();
                    }
                    throw new SerializationException("Unable to deserialize the response.", _responseContent, ex);
                }
            }
            if (_shouldTrace)
            {
                ServiceClientTracing.Exit(_invocationId, _result);
            }
            return(_result);
        }
        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, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"AMS v3 Function - CreateStreamingPolicy was triggered!");

            string  requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            if (data.streamingPolicyName == null)
            {
                return(new BadRequestObjectResult("Please pass streamingPolicyName in the input object"));
            }
            if (data.defaultContentKeyPolicyName == null)
            {
                return(new BadRequestObjectResult("Please pass defaultContentKeyPolicyName in the input object"));
            }
            string streamingPolicyName         = data.streamingPolicyName;
            string defaultContentKeyPolicyName = data.defaultContentKeyPolicyName;

            string mode = data.mode;

            if (mode != "simple" && mode != "advanced")
            {
                return(new BadRequestObjectResult("Please pass valid mode in the input object"));
            }
            //
            // Simple Mode
            //
            if (mode == "simple")
            {
                if (data.noEncryptionProtocols == null &&
                    data.cbcsProtocols == null &&
                    data.cencProtocols == null &&
                    data.envelopeProtocols == null)
                {
                    return(new BadRequestObjectResult("Please pass one protocol for any encryption scheme at least in the input object"));
                }
            }
            //
            // Advanced Mode
            //
            if (mode == "advanced")
            {
                if (data.jsonNoEncryption == null &&
                    data.jsonCommonEncryptionCbcs == null &&
                    data.jsonCommonEncryptionCenc == null &&
                    data.jsonEnvelopeEncryption == null)
                {
                    return(new BadRequestObjectResult("Please pass one encryption scheme JSON at least in the input object"));
                }
            }

            MediaServicesConfigWrapper amsconfig = new MediaServicesConfigWrapper();
            StreamingPolicy            policy    = null;

            JsonConverter[] jsonReaders =
            {
                new MediaServicesHelperJsonReader(),
                new MediaServicesHelperTimeSpanJsonConverter()
            };

            try
            {
                IAzureMediaServicesClient client = MediaServicesHelper.CreateMediaServicesClientAsync(amsconfig);

                policy = client.StreamingPolicies.Get(amsconfig.ResourceGroup, amsconfig.AccountName, streamingPolicyName);
                if (policy == null)
                {
                    StreamingPolicy parameters = new StreamingPolicy();
                    parameters.DefaultContentKeyPolicyName = defaultContentKeyPolicyName;

                    if (mode == "simple")
                    {
                        // NoEncryption Arguments
                        if (data.noEncryptionProtocols != null)
                        {
                            String[] noEncryptionProtocols = data.noEncryptionProtocols.ToString().Split(';');
                            if (Array.IndexOf(noEncryptionProtocols, "Dash") > -1)
                            {
                                parameters.NoEncryption.EnabledProtocols.Dash = true;
                            }
                            if (Array.IndexOf(noEncryptionProtocols, "Download") > -1)
                            {
                                parameters.NoEncryption.EnabledProtocols.Download = true;
                            }
                            if (Array.IndexOf(noEncryptionProtocols, "Hls") > -1)
                            {
                                parameters.NoEncryption.EnabledProtocols.Hls = true;
                            }
                            if (Array.IndexOf(noEncryptionProtocols, "SmoothStreaming") > -1)
                            {
                                parameters.NoEncryption.EnabledProtocols.SmoothStreaming = true;
                            }
                        }

                        // Common Encryption CBCS Argument
                        if (data.cbcsClearTracks != null)
                        {
                            List <TrackSelection> tracks = JsonConvert.DeserializeObject <List <TrackSelection> >(data.cbcsClearTracks.ToString(), jsonReaders);
                            parameters.CommonEncryptionCbcs.ClearTracks = tracks;
                        }
                        if (data.cbcsDefaultKeyLabel != null)
                        {
                            parameters.CommonEncryptionCbcs.ContentKeys.DefaultKey.Label = data.cbcsDefaultKeyLabel;
                        }
                        if (data.cbcsDefaultKeyPolicyName != null)
                        {
                            parameters.CommonEncryptionCbcs.ContentKeys.DefaultKey.PolicyName = data.cbcsDefaultKeyPolicyName;
                        }
                        if (data.cbcsClearTracks != null)
                        {
                            List <StreamingPolicyContentKey> mappings = JsonConvert.DeserializeObject <List <StreamingPolicyContentKey> >(data.cbcsKeyToTrackMappings.ToString(), jsonReaders);
                            parameters.CommonEncryptionCbcs.ContentKeys.KeyToTrackMappings = mappings;
                        }
                        if (data.cbcsFairPlayTemplate != null)
                        {
                            parameters.CommonEncryptionCbcs.Drm.FairPlay.CustomLicenseAcquisitionUrlTemplate = data.cbcsFairPlayTemplate;
                        }
                        if (data.cbcsFairPlayAllowPersistentLicense != null)
                        {
                            parameters.CommonEncryptionCbcs.Drm.FairPlay.AllowPersistentLicense = data.cbcsFairPlayAllowPersistentLicense;
                        }
                        if (data.cbcsPlayReadyTemplate != null)
                        {
                            parameters.CommonEncryptionCbcs.Drm.PlayReady.CustomLicenseAcquisitionUrlTemplate = data.cbcsPlayReadyTemplate;
                        }
                        if (data.cbcsPlayReadyAttributes != null)
                        {
                            parameters.CommonEncryptionCbcs.Drm.PlayReady.PlayReadyCustomAttributes = data.cbcsPlayReadyAttributes;
                        }
                        if (data.cbcsWidevineTemplate != null)
                        {
                            parameters.CommonEncryptionCbcs.Drm.Widevine.CustomLicenseAcquisitionUrlTemplate = data.cbcsWidevineTemplate;
                        }
                        if (data.cbcsProtocols != null)
                        {
                            String[] commonEncryptionCbcsProtocols = data.cbcsProtocols.ToString().Split(';');
                            if (Array.IndexOf(commonEncryptionCbcsProtocols, "Dash") > -1)
                            {
                                parameters.CommonEncryptionCbcs.EnabledProtocols.Dash = true;
                            }
                            if (Array.IndexOf(commonEncryptionCbcsProtocols, "Download") > -1)
                            {
                                parameters.CommonEncryptionCbcs.EnabledProtocols.Download = true;
                            }
                            if (Array.IndexOf(commonEncryptionCbcsProtocols, "Hls") > -1)
                            {
                                parameters.CommonEncryptionCbcs.EnabledProtocols.Hls = true;
                            }
                            if (Array.IndexOf(commonEncryptionCbcsProtocols, "SmoothStreaming") > -1)
                            {
                                parameters.CommonEncryptionCbcs.EnabledProtocols.SmoothStreaming = true;
                            }
                        }

                        // Common Encryption CENC Argument
                        if (data.cencClearTracks != null)
                        {
                            List <TrackSelection> tracks = JsonConvert.DeserializeObject <List <TrackSelection> >(data.cencClearTracks.ToString(), jsonReaders);
                            parameters.CommonEncryptionCenc.ClearTracks = tracks;
                        }
                        if (data.cencDefaultKeyLabel != null)
                        {
                            parameters.CommonEncryptionCenc.ContentKeys.DefaultKey.Label = data.cencDefaultKeyLabel;
                        }
                        if (data.cencDefaultKeyPolicyName != null)
                        {
                            parameters.CommonEncryptionCenc.ContentKeys.DefaultKey.PolicyName = data.cencDefaultKeyPolicyName;
                        }
                        if (data.cencClearTracks != null)
                        {
                            List <StreamingPolicyContentKey> mappings = JsonConvert.DeserializeObject <List <StreamingPolicyContentKey> >(data.cencKeyToTrackMappings.ToString(), jsonReaders);
                            parameters.CommonEncryptionCenc.ContentKeys.KeyToTrackMappings = mappings;
                        }
                        if (data.cencPlayReadyTemplate != null)
                        {
                            parameters.CommonEncryptionCenc.Drm.PlayReady.CustomLicenseAcquisitionUrlTemplate = data.cencPlayReadyTemplate;
                        }
                        if (data.cencPlayReadyAttributes != null)
                        {
                            parameters.CommonEncryptionCenc.Drm.PlayReady.PlayReadyCustomAttributes = data.cencPlayReadyAttributes;
                        }
                        if (data.cencWidevineTemplate != null)
                        {
                            parameters.CommonEncryptionCenc.Drm.Widevine.CustomLicenseAcquisitionUrlTemplate = data.cencWidevineTemplate;
                        }
                        if (data.cencProtocols != null)
                        {
                            String[] commonEncryptionCencProtocols = data.cencProtocols.ToString().Split(';');
                            if (Array.IndexOf(commonEncryptionCencProtocols, "Dash") > -1)
                            {
                                parameters.CommonEncryptionCenc.EnabledProtocols.Dash = true;
                            }
                            if (Array.IndexOf(commonEncryptionCencProtocols, "Download") > -1)
                            {
                                parameters.CommonEncryptionCenc.EnabledProtocols.Download = true;
                            }
                            if (Array.IndexOf(commonEncryptionCencProtocols, "Hls") > -1)
                            {
                                parameters.CommonEncryptionCenc.EnabledProtocols.Hls = true;
                            }
                            if (Array.IndexOf(commonEncryptionCencProtocols, "SmoothStreaming") > -1)
                            {
                                parameters.CommonEncryptionCenc.EnabledProtocols.SmoothStreaming = true;
                            }
                        }

                        // Envelope Encryption Argument
                        if (data.envelopeClearTracks != null || data.envelopeDefaultKeyLabel != null || data.envelopeDefaultKeyPolicyName != null ||
                            data.envelopeClearTracks || data.envelopeTemplate != null || data.envelopeTemplate != null || data.envelopeProtocols != null)
                        {
                            parameters.EnvelopeEncryption = new EnvelopeEncryption();
                            if (data.envelopeClearTracks != null)
                            {
                                List <TrackSelection> tracks = JsonConvert.DeserializeObject <List <TrackSelection> >(data.envelopeClearTracks.ToString(), jsonReaders);
                                parameters.EnvelopeEncryption.ClearTracks = tracks;
                            }

                            parameters.EnvelopeEncryption.ContentKeys            = new StreamingPolicyContentKeys();
                            parameters.EnvelopeEncryption.ContentKeys.DefaultKey = new DefaultKey(data.envelopeDefaultKeyLabel as string, data.envelopeDefaultKeyPolicyName as string);
                            if (data.envelopeClearTracks != null)
                            {
                                List <StreamingPolicyContentKey> mappings = JsonConvert.DeserializeObject <List <StreamingPolicyContentKey> >(data.envelopeKeyToTrackMappings.ToString(), jsonReaders);
                                parameters.EnvelopeEncryption.ContentKeys.KeyToTrackMappings = mappings;
                            }

                            if (data.envelopeTemplate != null)
                            {
                                parameters.EnvelopeEncryption.CustomKeyAcquisitionUrlTemplate = data.envelopeTemplate;
                            }
                            if (data.envelopeProtocols != null)
                            {
                                parameters.EnvelopeEncryption.EnabledProtocols = new EnabledProtocols();
                                String[] envelopeEncryptionProtocols = data.envelopeProtocols.ToString().Split(';');
                                if (Array.IndexOf(envelopeEncryptionProtocols, "Dash") > -1)
                                {
                                    parameters.EnvelopeEncryption.EnabledProtocols.Dash = true;
                                }
                                if (Array.IndexOf(envelopeEncryptionProtocols, "Download") > -1)
                                {
                                    parameters.EnvelopeEncryption.EnabledProtocols.Download = true;
                                }
                                if (Array.IndexOf(envelopeEncryptionProtocols, "Hls") > -1)
                                {
                                    parameters.EnvelopeEncryption.EnabledProtocols.Hls = true;
                                }
                                if (Array.IndexOf(envelopeEncryptionProtocols, "SmoothStreaming") > -1)
                                {
                                    parameters.EnvelopeEncryption.EnabledProtocols.SmoothStreaming = true;
                                }
                            }
                        }
                    }
                    else if (mode == "advanced")
                    {
                        NoEncryption         noEncryptionArguments         = null;
                        CommonEncryptionCbcs commonEncryptionCbcsArguments = null;
                        CommonEncryptionCenc commonEncryptionCencArguments = null;
                        EnvelopeEncryption   envelopeEncryptionArguments   = null;

                        if (data.jsonNoEncryption != null)
                        {
                            noEncryptionArguments = JsonConvert.DeserializeObject <NoEncryption>(data.configNoEncryption.ToString(), jsonReaders);
                        }
                        if (data.jsonCommonEncryptionCbcs != null)
                        {
                            commonEncryptionCbcsArguments = JsonConvert.DeserializeObject <CommonEncryptionCbcs>(data.jsonCommonEncryptionCbcs.ToString(), jsonReaders);
                        }
                        if (data.jsonCommonEncryptionCenc != null)
                        {
                            commonEncryptionCencArguments = JsonConvert.DeserializeObject <CommonEncryptionCenc>(data.jsonCommonEncryptionCenc.ToString(), jsonReaders);
                        }
                        if (data.jsonEnvelopeEncryption != null)
                        {
                            envelopeEncryptionArguments = JsonConvert.DeserializeObject <EnvelopeEncryption>(data.jsonEnvelopeEncryption.ToString(), jsonReaders);
                        }
                        parameters.NoEncryption         = noEncryptionArguments;
                        parameters.CommonEncryptionCbcs = commonEncryptionCbcsArguments;
                        parameters.CommonEncryptionCenc = commonEncryptionCencArguments;
                        parameters.EnvelopeEncryption   = envelopeEncryptionArguments;
                    }
                    parameters.Validate();
                    policy = client.StreamingPolicies.Create(amsconfig.ResourceGroup, amsconfig.AccountName, streamingPolicyName, parameters);
                }
            }
            catch (ApiErrorException e)
            {
                log.LogError($"ERROR: AMS API call failed with error code: {e.Body.Error.Code} and message: {e.Body.Error.Message}");
                return(new BadRequestObjectResult("AMS API call error: " + e.Message + "\nError Code: " + e.Body.Error.Code + "\nMessage: " + e.Body.Error.Message));
            }
            catch (Exception e)
            {
                log.LogError($"ERROR: Exception with message: {e.Message}");
                return(new BadRequestObjectResult("Error: " + e.Message));
            }

            return((ActionResult) new OkObjectResult(new
            {
                streamingPolicyName = streamingPolicyName,
                streamingPolicyId = policy.Id
            }));
        }
示例#11
0
 /// <summary>
 /// Create a Streaming Policy
 /// </summary>
 /// <remarks>
 /// Create a Streaming Policy in the Media Services account
 /// </remarks>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group within the Azure subscription.
 /// </param>
 /// <param name='accountName'>
 /// The Media Services account name.
 /// </param>
 /// <param name='streamingPolicyName'>
 /// The Streaming Policy name.
 /// </param>
 /// <param name='parameters'>
 /// The request parameters
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task <StreamingPolicy> CreateAsync(this IStreamingPoliciesOperations operations, string resourceGroupName, string accountName, string streamingPolicyName, StreamingPolicy parameters, CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var _result = await operations.CreateWithHttpMessagesAsync(resourceGroupName, accountName, streamingPolicyName, parameters, null, cancellationToken).ConfigureAwait(false))
     {
         return(_result.Body);
     }
 }
示例#12
0
 /// <summary>
 /// Create a Streaming Policy
 /// </summary>
 /// <remarks>
 /// Create a Streaming Policy in the Media Services account
 /// </remarks>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group within the Azure subscription.
 /// </param>
 /// <param name='accountName'>
 /// The Media Services account name.
 /// </param>
 /// <param name='streamingPolicyName'>
 /// The Streaming Policy name.
 /// </param>
 /// <param name='parameters'>
 /// The request parameters
 /// </param>
 public static StreamingPolicy Create(this IStreamingPoliciesOperations operations, string resourceGroupName, string accountName, string streamingPolicyName, StreamingPolicy parameters)
 {
     return(operations.CreateAsync(resourceGroupName, accountName, streamingPolicyName, parameters).GetAwaiter().GetResult());
 }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"AMS v3 Function - PublishAsset was triggered!");

            string  requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            // Validate input objects
            if (data.assetName == null)
            {
                return(new BadRequestObjectResult("Please pass assetName in the input object"));
            }
            if (data.streamingPolicyName == null)
            {
                return(new BadRequestObjectResult("Please pass streamingPolicyName in the input object"));
            }
            string assetName           = data.assetName;
            string streamingPolicyName = data.streamingPolicyName;
            string alternativeMediaId  = null;

            if (data.alternativeMediaId != null)
            {
                alternativeMediaId = data.alternativeMediaId;
            }
            string contentKeyPolicyName = null;

            if (data.contentKeyPolicyName != null)
            {
                contentKeyPolicyName = data.contentKeyPolicyName;
            }
            List <StreamingLocatorContentKey> contentKeys = new List <StreamingLocatorContentKey>();
            DateTime startDateTime = new DateTime(0);

            if (data.startDateTime != null)
            {
                startDateTime = data.startDateTime;
            }
            DateTime endDateTime = new DateTime(0);

            if (data.endDateTime != null)
            {
                endDateTime = data.endDateTime;
            }
            Guid streamingLocatorId = Guid.NewGuid();

            if (data.streamingLocatorId != null)
            {
                streamingLocatorId = new Guid((string)(data.streamingLocatorId));
            }
            string streamingLocatorName = "streaminglocator-" + streamingLocatorId.ToString();

            MediaServicesConfigWrapper amsconfig        = new MediaServicesConfigWrapper();
            StreamingLocator           streamingLocator = null;
            Asset           asset           = null;
            StreamingPolicy streamingPolicy = null;

            try
            {
                IAzureMediaServicesClient client = MediaServicesHelper.CreateMediaServicesClientAsync(amsconfig);

                asset = client.Assets.Get(amsconfig.ResourceGroup, amsconfig.AccountName, assetName);
                if (asset == null)
                {
                    return(new BadRequestObjectResult("Asset not found"));
                }
                streamingPolicy = client.StreamingPolicies.Get(amsconfig.ResourceGroup, amsconfig.AccountName, streamingPolicyName);
                if (streamingPolicy == null)
                {
                    return(new BadRequestObjectResult("StreamingPolicy not found"));
                }
                if (contentKeyPolicyName != null)
                {
                    ContentKeyPolicy contentKeyPolicy = null;
                    contentKeyPolicy = client.ContentKeyPolicies.Get(amsconfig.ResourceGroup, amsconfig.AccountName, contentKeyPolicyName);
                    if (contentKeyPolicy == null)
                    {
                        return(new BadRequestObjectResult("ContentKeyPolicy not found"));
                    }
                }
                if (data.contentKeys != null)
                {
                    JsonConverter[] jsonConverters =
                    {
                        new MediaServicesHelperJsonReader()
                    };
                    contentKeys = JsonConvert.DeserializeObject <List <StreamingLocatorContentKey> >(data.contentKeys.ToString(), jsonConverters);
                }

                streamingLocator = new StreamingLocator()
                {
                    AssetName                   = assetName,
                    StreamingPolicyName         = streamingPolicyName,
                    AlternativeMediaId          = alternativeMediaId,
                    DefaultContentKeyPolicyName = contentKeyPolicyName,
                    StartTime                   = null,
                    EndTime            = null,
                    StreamingLocatorId = streamingLocatorId,
                };
                if (!startDateTime.Equals(new DateTime(0)))
                {
                    streamingLocator.StartTime = startDateTime;
                }
                if (!endDateTime.Equals(new DateTime(0)))
                {
                    streamingLocator.EndTime = endDateTime;
                }
                if (contentKeys.Count != 0)
                {
                    streamingLocator.ContentKeys = contentKeys;
                }
                streamingLocator.Validate();

                client.StreamingLocators.Create(amsconfig.ResourceGroup, amsconfig.AccountName, streamingLocatorName, streamingLocator);
            }
            catch (ApiErrorException e)
            {
                log.LogError($"ERROR: AMS API call failed with error code: {e.Body.Error.Code} and message: {e.Body.Error.Message}");
                return(new BadRequestObjectResult("AMS API call error: " + e.Message + "\nError Code: " + e.Body.Error.Code + "\nMessage: " + e.Body.Error.Message));
            }
            catch (Exception e)
            {
                log.LogError($"ERROR: Exception with message: {e.Message}");
                return(new BadRequestObjectResult("Error: " + e.Message));
            }

            return((ActionResult) new OkObjectResult(new
            {
                streamingLocatorName = streamingLocatorName,
                streamingLocatorId = streamingLocator.StreamingLocatorId.ToString()
            }));
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequest req, ILogger log)
        {
            log.LogInformation("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);
            }

            // semaphore file (json structure)
            VodSemaphore semaphore = null;

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


            // init default
            var streamingLocatorGuid = Guid.NewGuid(); // same locator for the two ouputs if 2 live event namle created
            var uniquenessLocator    = streamingLocatorGuid.ToString().Substring(0, 13);
            var streamingLocatorName = "locator-" + uniquenessLocator;

            string uniquenessPolicyName = Guid.NewGuid().ToString().Substring(0, 13);

            // useDRM init
            var useDRM = true;

            if (data.useDRM != null)
            {
                useDRM = (bool)data.useDRM;
            }
            else if (semaphore != null & semaphore.ClearStream != null)
            {
                useDRM = !(bool)semaphore.ClearStream;
            }


            // Default content id and semaphare value
            string irdetoContentId = null;

            if (semaphore != null && semaphore.DrmContentId != null) // semaphore data has higher priority
            {
                irdetoContentId = semaphore.DrmContentId;
            }
            else if (data.defaultIrdetoContentId != null)
            {
                irdetoContentId = (string)data.defaultIrdetoContentId;
            }

            DateTime?startTime = null;
            DateTime?endTime   = null;

            try
            {
                if (semaphore != null && semaphore.StartTime != null)
                {
                    startTime = DateTime.ParseExact(semaphore.StartTime, AssetEntry.DateFormat, System.Globalization.CultureInfo.InvariantCulture);
                }
                if (semaphore != null && semaphore.EndTime != null)
                {
                    endTime = DateTime.ParseExact(semaphore.EndTime, AssetEntry.DateFormat, System.Globalization.CultureInfo.InvariantCulture);
                }
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }


            var cencKey = new StreamingLocatorContentKey();
            var cbcsKey = new StreamingLocatorContentKey();

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

                    MediaServicesHelpers.LogInformation(log, "Irdeto call...");

                    cencKey = await IrdetoHelpers.GenerateAndRegisterCENCKeyToIrdeto(irdetoContentId, config);

                    cbcsKey = await IrdetoHelpers.GenerateAndRegisterCBCSKeyToIrdeto(irdetoContentId, config);

                    MediaServicesHelpers.LogInformation(log, "Irdeto call done.");
                }
                catch (Exception ex)
                {
                    return(IrdetoHelpers.ReturnErrorException(log, ex, "Irdeto response error"));
                }
            }

            var clientTasks = new List <Task <AssetEntry> >();

            foreach (var region in azureRegions)
            {
                var task = Task <AssetEntry> .Run(async() =>
                {
                    Asset asset = null;
                    StreamingPolicy streamingPolicy = null;

                    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;

                    if (useDRM)
                    {
                        MediaServicesHelpers.LogInformation(log, "Trying to read streaming policy from Cosmos.", region);
                        string streamingPolicyName = null;
                        // Load streaming policy info from Cosmos
                        try
                        {
                            var info = await CosmosHelpers.ReadStreamingPolicyDocument(new StreamingPolicyInfo(true)
                            {
                                AMSAccountName = config.AccountName
                            });

                            if (info == null)
                            {
                                log.LogWarning("Streaming policy not read from Cosmos.");
                            }
                            else
                            {
                                streamingPolicyName = info.StreamingPolicyName;
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("Error reading Cosmos DB", ex);
                        }


                        // STREAMING POLICY CREATION
                        if (streamingPolicyName == null) // not found in Cosmos let's create a new one
                        {
                            MediaServicesHelpers.LogInformation(log, "Creating streaming policy.", region);
                            try
                            {
                                streamingPolicy = await IrdetoHelpers.CreateStreamingPolicyIrdeto(config, client, uniquenessPolicyName);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Streaming policy creation error", ex);
                            }

                            try
                            {
                                if (!await CosmosHelpers.CreateOrUpdatePolicyDocument(new StreamingPolicyInfo(true)
                                {
                                    AMSAccountName = config.AccountName,
                                    StreamingPolicyName = streamingPolicy.Name
                                }))
                                {
                                    log.LogWarning("Cosmos access not configured or error.");
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Streaming policy write error to Cosmos", ex);
                            }
                        }
                        else
                        {
                            MediaServicesHelpers.LogInformation(log, "Getting streaming policy in AMS.", region);
                            try
                            {
                                streamingPolicy = await client.StreamingPolicies.GetAsync(config.ResourceGroup, config.AccountName, streamingPolicyName);
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Error when getting streaming policy " + streamingPolicy, ex);
                            }
                        }
                    }


                    // let's get the asset
                    try
                    {
                        MediaServicesHelpers.LogInformation(log, "Getting asset.", region);
                        asset = await client.Assets.GetAsync(config.ResourceGroup, config.AccountName, assetName);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error when retreving asset by name", ex);
                    }


                    // Locator creation
                    try
                    {
                        StreamingLocator locator = null;
                        if (useDRM)
                        {
                            locator = await IrdetoHelpers.SetupDRMAndCreateLocatorWithNewKeys(config, streamingPolicy.Name,
                                                                                              streamingLocatorName, client, asset, cencKey, cbcsKey, streamingLocatorGuid, irdetoContentId, startTime, endTime);
                        }
                        else // no DRM
                        {
                            locator = await IrdetoHelpers.CreateClearLocator(config, streamingLocatorName, client, asset, streamingLocatorGuid, startTime, endTime);
                        }

                        MediaServicesHelpers.LogInformation(log, "locator : " + locator.Name, region);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error when creating the locator", ex);
                    }


                    // let's build info for the live event and output

                    AssetEntry assetEntry = await GenerateInfoHelpers.GenerateAssetInformation(config, client, asset, semaphore, irdetoContentId, region);

                    if (!await CosmosHelpers.CreateOrUpdateAssetDocument(assetEntry))
                    {
                        log.LogWarning("Cosmos access not configured.");
                    }

                    return(assetEntry);
                });

                clientTasks.Add(task);
            }

            try
            {
                Task.WaitAll(clientTasks.ToArray());
            }
            catch (Exception ex)
            {
                return(IrdetoHelpers.ReturnErrorException(log, ex));
            }

            return(new OkObjectResult(
                       JsonConvert.SerializeObject(new VodAssetInfo {
                Success = true, Assets = clientTasks.Select(i => i.Result).ToList()
            }, Formatting.Indented)
                       ));
        }
        public static GeneralOutputInfo GenerateOutputInformation(ConfigWrapper config,
                                                                  IAzureMediaServicesClient client, List <LiveEvent> liveEvents)
        {
            var generalOutputInfo = new GeneralOutputInfo {
                Success = true, LiveEvents = new List <LiveEventEntry>()
            };

            foreach (var liveEventenum in liveEvents)
            {
                var liveEvent =
                    client.LiveEvents.Get(config.ResourceGroup, config.AccountName,
                                          liveEventenum.Name); // we refresh the object

                var liveOutputs = client.LiveOutputs.List(config.ResourceGroup, config.AccountName, liveEvent.Name);

                // let's provide DASH format for preview
                var previewE = liveEvent.Preview.Endpoints
                               .Select(a => new PreviewInfo {
                    Protocol = a.Protocol, Url = a.Url
                }).ToList();

                /*
                 * // Code to expose Preview DASH and not Smooth
                 * if (previewE.Count == 1 && previewE[0].Protocol == "FragmentedMP4")
                 * {
                 *  previewE[0].Protocol = "DashCsf";
                 *  previewE[0].Url = previewE[0].Url + "(format=mpd-time-csf)";
                 * }
                 */


                // output info
                var liveEventInfo = new LiveEventEntry()
                {
                    LiveEventName = liveEvent.Name,
                    ResourceState = liveEvent.ResourceState.ToString(),
                    VanityUrl     = liveEvent.VanityUrl,
                    Input         = liveEvent.Input.Endpoints
                                    .Select(endPoint => new UrlEntry {
                        Protocol = endPoint.Protocol, Url = endPoint.Url
                    }).ToList(),
                    InputACL = liveEvent.Input.AccessControl?.Ip.Allow
                               .Select(ip => ip.Address + "/" + ip.SubnetPrefixLength).ToList(),
                    Preview = previewE
                              .Select(endPoint => new UrlEntry {
                        Protocol = endPoint.Protocol, Url = endPoint.Url
                    }).ToList(),
                    PreviewACL = liveEvent.Preview.AccessControl?.Ip.Allow
                                 .Select(ip => ip.Address + "/" + ip.SubnetPrefixLength).ToList(),
                    LiveOutputs    = new List <LiveOutputEntry>(),
                    AMSAccountName = config.AccountName,
                    Region         = config.Region,
                    ResourceGroup  = config.ResourceGroup,
                    LowLatency     = liveEvent.StreamOptions?.Contains(StreamOptionsFlag.LowLatency)
                };
                generalOutputInfo.LiveEvents.Add(liveEventInfo);

                foreach (var liveOutput in liveOutputs)
                {
                    var             urls = new List <OutputUrl>();
                    string          streamingPolicyName = null;
                    StreamingPolicy streamingPolicy     = null;

                    var asset = client.Assets.Get(config.ResourceGroup, config.AccountName, liveOutput.AssetName);

                    // output info
                    var liveOutputInfo = new LiveOutputEntry
                    {
                        LiveOutputName          = liveOutput.Name,
                        ResourceState           = liveOutput.ResourceState,
                        ArchiveWindowLength     = (int)liveOutput.ArchiveWindowLength.TotalMinutes,
                        AssetName               = liveOutput.AssetName,
                        AssetStorageAccountName = asset?.StorageAccountName,
                        StreamingLocators       = new List <StreamingLocatorEntry>()
                    };
                    liveEventInfo.LiveOutputs.Add(liveOutputInfo);

                    var streamingLocatorsNames = client.Assets.ListStreamingLocators(config.ResourceGroup, config.AccountName, liveOutput.AssetName).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();
                                }

                                urls = MediaServicesHelpers.GetUrls(config, client, streamingLocator,
                                                                    liveOutput.ManifestName, true, true, true, true, true);
                            }
                        }

                        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()
                        };

                        liveOutputInfo.StreamingLocators.Add(StreamingLocatorInfo);
                    }
                }
            }

            return(generalOutputInfo);
        }
 /// <inheritdoc/>
 public Task <StreamingPolicy> StreamingPolicyCreateAsync(string streamingPolicyName, StreamingPolicy parameters, CancellationToken cancellationToken = default) => _client.StreamingPolicies.CreateAsync(_amsResourceGroup, _amsAccountName, streamingPolicyName, parameters, cancellationToken);