Configure asset delivery policies with .NET SDK

Overview

If you plan to delivery encrypted assets, one of the steps in the Media Services content delivery workflow is configuring delivery policies for assets. The asset delivery policy tells Media Services how you want for your asset to be delivered: into which streaming protocol should your asset be dynamically packaged (for example, MPEG DASH, HLS, Smooth Streaming, or all), whether or not you want to dynamically encrypt your asset and how (envelope or common encryption).

This article discusses why and how to create and configure asset delivery policies.

Note

When your AMS account is created, a default streaming endpoint is added to your account in the Stopped state. To start streaming your content and take advantage of dynamic packaging and dynamic encryption, the streaming endpoint from which you want to stream content has to be in the Running state.

Also, to be able to use dynamic packaging and dynamic encryption your asset must contain a set of adaptive bitrate MP4s or adaptive bitrate Smooth Streaming files.

You could apply different policies to the same asset. For example, you could apply PlayReady encryption to Smooth Streaming and AES Envelope encryption to MPEG DASH and HLS. Any protocols that are not defined in a delivery policy (for example, you add a single policy that only specifies HLS as the protocol) will be blocked from streaming. The exception is if you have no asset delivery policy defined at all. Then, all protocols will be allowed in the clear.

If you want to deliver a storage encrypted asset, you must configure the asset’s delivery policy. Before your asset can be streamed, the streaming server removes the storage encryption and streams your content using the specified delivery policy. For example, to deliver your asset encrypted with Advanced Encryption Standard (AES) envelope encryption key, set the policy type to DynamicEnvelopeEncryption. To remove storage encryption and stream the asset in the clear, set the policy type to NoDynamicEncryption. Examples that show how to configure these policy types follow.

Depending on how you configure the asset delivery policy, you can dynamically package, encrypt, and stream the following streaming protocols: Smooth Streaming, HLS, and MPEG DASH.

The following list shows the formats that you use to stream Smooth, HLS, and DASH.

Smooth Streaming:

{streaming endpoint name-media services account name}.streaming.mediaservices.windows.net/{locator ID}/{filename}.ism/Manifest

HLS:

{streaming endpoint name-media services account name}.streaming.mediaservices.windows.net/{locator ID}/{filename}.ism/Manifest(format=m3u8-aapl)

MPEG DASH

{streaming endpoint name-media services account name}.streaming.mediaservices.windows.net/{locator ID}/{filename}.ism/Manifest(format=mpd-time-csf)

Considerations

  • Before deleting the AssetDeliveryPolicy, you should delete all of the streaming locators associated with the asset. You can later create new streaming locators, if desired, with a new AssetDeliveryPolicy.
  • A streaming locator cannot be created on a storage encrypted asset when no asset delivery policy is set. If the Asset isn’t storage encrypted, the system will let you create a locator and stream the asset in the clear without an asset delivery policy.
  • You can have multiple asset delivery policies associated with a single asset but you can only specify one way to handle a given AssetDeliveryProtocol. Meaning if you try to link two delivery policies that specify the AssetDeliveryProtocol.SmoothStreaming protocol that will result in an error because the system does not know which one you want it to apply when a client makes a Smooth Streaming request.
  • If you have an asset with an existing streaming locator, you cannot link a new policy to the asset (you can either unlink an existing policy from the asset, or update a delivery policy associated with the asset). You first have to remove the streaming locator, adjust the policies, and then re-create the streaming locator. You can use the same locatorId when you recreate the streaming locator but you should ensure that won’t cause issues for clients since content can be cached by the origin or a downstream CDN.

Clear asset delivery policy

The following ConfigureClearAssetDeliveryPolicy method specifies to not apply dynamic encryption and to deliver the stream in any of the following protocols: MPEG DASH, HLS, and Smooth Streaming protocols. You might want to apply this policy to your storage encrypted assets.

For information on what values you can specify when creating an AssetDeliveryPolicy, see the Types used when defining AssetDeliveryPolicy section.

	static public void ConfigureClearAssetDeliveryPolicy(IAsset asset)
	{
		IAssetDeliveryPolicy policy =
		_context.AssetDeliveryPolicies.Create("Clear Policy",
		AssetDeliveryPolicyType.NoDynamicEncryption,
		AssetDeliveryProtocol.HLS | AssetDeliveryProtocol.SmoothStreaming | AssetDeliveryProtocol.Dash, null);

		asset.DeliveryPolicies.Add(policy);
	}

DynamicCommonEncryption asset delivery policy

The following CreateAssetDeliveryPolicy method creates the AssetDeliveryPolicy that is configured to apply dynamic common encryption (DynamicCommonEncryption) to a smooth streaming protocol (other protocols will be blocked from streaming). The method takes two parameters: Asset (the asset to which you want to apply the delivery policy) and IContentKey (the content key of the CommonEncryption type, for more information, see: Creating a content key).

For information on what values you can specify when creating an AssetDeliveryPolicy, see the Types used when defining AssetDeliveryPolicy section.

	static public void CreateAssetDeliveryPolicy(IAsset asset, IContentKey key)
	{
		Uri acquisitionUrl = key.GetKeyDeliveryUrl(ContentKeyDeliveryType.PlayReadyLicense);

		Dictionary<AssetDeliveryPolicyConfigurationKey, string> assetDeliveryPolicyConfiguration =
	            new Dictionary<AssetDeliveryPolicyConfigurationKey, string>
	        {
	            {AssetDeliveryPolicyConfigurationKey.PlayReadyLicenseAcquisitionUrl, acquisitionUrl.ToString()},
	        };

	        var assetDeliveryPolicy = _context.AssetDeliveryPolicies.Create(
	                "AssetDeliveryPolicy",
	            AssetDeliveryPolicyType.DynamicCommonEncryption,
	            AssetDeliveryProtocol.SmoothStreaming,
	            assetDeliveryPolicyConfiguration);

	        // Add AssetDelivery Policy to the asset
	        asset.DeliveryPolicies.Add(assetDeliveryPolicy);

	        Console.WriteLine();
	        Console.WriteLine("Adding Asset Delivery Policy: " +
	            assetDeliveryPolicy.AssetDeliveryPolicyType);
	 }

Azure Media Services also enables you to add Widevine encryption. The following example demonstrates both PlayReady and Widevine being added to the asset delivery policy.

    static public void CreateAssetDeliveryPolicy(IAsset asset, IContentKey key)
    {
        // Get the PlayReady license service URL.
        Uri acquisitionUrl = key.GetKeyDeliveryUrl(ContentKeyDeliveryType.PlayReadyLicense);


        // GetKeyDeliveryUrl for Widevine attaches the KID to the URL.
        // For example: https://amsaccount1.keydelivery.mediaservices.windows.net/Widevine/?KID=268a6dcb-18c8-4648-8c95-f46429e4927c.
        // The WidevineBaseLicenseAcquisitionUrl (used below) also tells Dynamic Encryption
        // to append /? KID =< keyId > to the end of the url when creating the manifest.
        // As a result Widevine license acquisition URL will have KID appended twice,
        // so we need to remove the KID that in the URL when we call GetKeyDeliveryUrl.

        Uri widevineUrl = key.GetKeyDeliveryUrl(ContentKeyDeliveryType.Widevine);
        UriBuilder uriBuilder = new UriBuilder(widevineUrl);
        uriBuilder.Query = String.Empty;
        widevineUrl = uriBuilder.Uri;

        Dictionary<AssetDeliveryPolicyConfigurationKey, string> assetDeliveryPolicyConfiguration =
            new Dictionary<AssetDeliveryPolicyConfigurationKey, string>
        {
            {AssetDeliveryPolicyConfigurationKey.PlayReadyLicenseAcquisitionUrl, acquisitionUrl.ToString()},
            {AssetDeliveryPolicyConfigurationKey.WidevineLicenseAcquisitionUrl, widevineUrl.ToString()}

        };

        var assetDeliveryPolicy = _context.AssetDeliveryPolicies.Create(
                "AssetDeliveryPolicy",
            AssetDeliveryPolicyType.DynamicCommonEncryption,
            AssetDeliveryProtocol.Dash,
            assetDeliveryPolicyConfiguration);


        // Add AssetDelivery Policy to the asset
        asset.DeliveryPolicies.Add(assetDeliveryPolicy);

    }

Note

When encrypting with Widevine, you would only be able to deliver using DASH. Make sure to specify DASH in the asset delivery protocol.

DynamicEnvelopeEncryption asset delivery policy

The following CreateAssetDeliveryPolicy method creates the AssetDeliveryPolicy that is configured to apply dynamic envelope encryption (DynamicEnvelopeEncryption) to Smooth Streaming, HLS, and DASH protocols (if you decide to not specify some protocols, they will be blocked from streaming). The method takes two parameters: Asset (the asset to which you want to apply the delivery policy) and IContentKey (the content key of the EnvelopeEncryption type, for more information, see: Creating a content key).

For information on what values you can specify when creating an AssetDeliveryPolicy, see the Types used when defining AssetDeliveryPolicy section.

    private static void CreateAssetDeliveryPolicy(IAsset asset, IContentKey key)
    {

        //  Get the Key Delivery Base Url by removing the Query parameter.  The Dynamic Encryption service will
        //  automatically add the correct key identifier to the url when it generates the Envelope encrypted content
        //  manifest.  Omitting the IV will also cause the Dynamic Encryption service to generate a deterministic
        //  IV for the content automatically.  By using the EnvelopeBaseKeyAcquisitionUrl and omitting the IV, this
        //  allows the AssetDelivery policy to be reused by more than one asset.
        //
        Uri keyAcquisitionUri = key.GetKeyDeliveryUrl(ContentKeyDeliveryType.BaselineHttp);
        UriBuilder uriBuilder = new UriBuilder(keyAcquisitionUri);
        uriBuilder.Query = String.Empty;
        keyAcquisitionUri = uriBuilder.Uri;

        // The following policy configuration specifies:
        //   key url that will have KID=<Guid> appended to the envelope and
        //   the Initialization Vector (IV) to use for the envelope encryption.
        Dictionary<AssetDeliveryPolicyConfigurationKey, string> assetDeliveryPolicyConfiguration =
            new Dictionary<AssetDeliveryPolicyConfigurationKey, string>
        {
            {AssetDeliveryPolicyConfigurationKey.EnvelopeBaseKeyAcquisitionUrl, keyAcquisitionUri.ToString()},
        };

        IAssetDeliveryPolicy assetDeliveryPolicy =
            _context.AssetDeliveryPolicies.Create(
                        "AssetDeliveryPolicy",
                        AssetDeliveryPolicyType.DynamicEnvelopeEncryption,
                        AssetDeliveryProtocol.SmoothStreaming | AssetDeliveryProtocol.HLS | AssetDeliveryProtocol.Dash,
                        assetDeliveryPolicyConfiguration);

        // Add AssetDelivery Policy to the asset
        asset.DeliveryPolicies.Add(assetDeliveryPolicy);

        Console.WriteLine();
        Console.WriteLine("Adding Asset Delivery Policy: " + assetDeliveryPolicy.AssetDeliveryPolicyType);
    }

Types used when defining AssetDeliveryPolicy

AssetDeliveryProtocol

The following enum describes values you can set for the asset delivery protocol.

    [Flags]
    public enum AssetDeliveryProtocol
    {
        /// <summary>
        /// No protocols.
        /// </summary>
        None = 0x0,

        /// <summary>
        /// Smooth streaming protocol.
        /// </summary>
        SmoothStreaming = 0x1,

        /// <summary>
        /// MPEG Dynamic Adaptive Streaming over HTTP (DASH)
        /// </summary>
        Dash = 0x2,

        /// <summary>
        /// Apple HTTP Live Streaming protocol.
        /// </summary>
        HLS = 0x4,

        ProgressiveDownload = 0x10,

        /// <summary>
        /// Include all protocols.
        /// </summary>
        All = 0xFFFF
    }

AssetDeliveryPolicyType

The following enum describes values you can set for the asset delivery policy type.

    public enum AssetDeliveryPolicyType
    {
        /// <summary>
        /// Delivery Policy Type not set.  An invalid value.
        /// </summary>
        None,

        /// <summary>
        /// The Asset should not be delivered via this AssetDeliveryProtocol.
        /// </summary>
        Blocked,

        /// <summary>
        /// Do not apply dynamic encryption to the asset.
        /// </summary>
        ///
        NoDynamicEncryption,

        /// <summary>
        /// Apply Dynamic Envelope encryption.
        /// </summary>
        DynamicEnvelopeEncryption,

        /// <summary>
        /// Apply Dynamic Common encryption.
        /// </summary>
        DynamicCommonEncryption
        }

ContentKeyDeliveryType

The following enum describes values you can use to configure the delivery method of the content key to the client.

  public enum ContentKeyDeliveryType
  {
      /// <summary>
      /// None.
      ///
      </summary>
      None = 0,

      /// <summary>
      /// Use PlayReady License acquisition protocol
      ///
      </summary>
      PlayReadyLicense = 1,

      /// <summary>
      /// Use MPEG Baseline HTTP key protocol.
      ///
      </summary>
      BaselineHttp = 2,

      /// <summary>
      /// Use Widevine License acquisition protocol
      ///
      </summary>
      Widevine = 3

  }

AssetDeliveryPolicyConfigurationKey

The following enum describes values you can set to configure keys used to get specific configuration for an asset delivery policy.

    public enum AssetDeliveryPolicyConfigurationKey
    {
        /// <summary>
        /// No policies.
        /// </summary>
        None,

        /// <summary>
        /// Exact Envelope key URL.
        /// </summary>
        EnvelopeKeyAcquisitionUrl,

        /// <summary>
        /// Base key url that will have KID=<Guid> appended for Envelope.
        /// </summary>
        EnvelopeBaseKeyAcquisitionUrl,

        /// <summary>
        /// The initialization vector to use for envelope encryption in Base64 format.
        /// </summary>
        EnvelopeEncryptionIVAsBase64,

        /// <summary>
        /// The PlayReady License Acquisition Url to use for common encryption.
        /// </summary>
        PlayReadyLicenseAcquisitionUrl,

        /// <summary>
        /// The PlayReady Custom Attributes to add to the PlayReady Content Header
        /// </summary>
        PlayReadyCustomAttributes,

        /// <summary>
        /// The initialization vector to use for envelope encryption.
        /// </summary>
        EnvelopeEncryptionIV,

        /// <summary>
        /// Widevine DRM acquisition url
        /// </summary>
        WidevineLicenseAcquisitionUrl
    }

Additional notes

  • Widevine is a service provided by Google Inc. and subject to the terms of service and Privacy Policy of Google, Inc.