Publishing assets with Windows Azure Media Services SDK for .NET

The last step we need to perform when working with Microsoft Azure Media Services is the publication of the final assets, in order that they can be consumed by users. From the Microsoft Azure portal, we can do this through PUBLISH button:

Publish content

However, if we have made the ingesting of assets from .NET, and have uploaded several files within the same asset, we see that if we make the publication from the portal it’ll only return us the URL of one of the files (it’s true that we can create the rest manually and use them but do not appear on the service site).

In this post I want to share the code required to make the publication from .NET, plus get all URLs of all files in an asset:

using Microsoft.WindowsAzure.MediaServices.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PublishAssets
{
    class Program
    {
        static void Main(string[] args)
        {

            //0. Constants
            const string AccountName = "[YOUR_ACCOUNT_NAME]";
            const string AccountKey = "[YOUR_ACCOUNT_KEY]";
            const string StreamingAssetName = "WOW_Mists_of_Pandaria_H264_Smooth";
            const string DownloadingAssetName = "WoW_Trailers";

            //1. Install-Package windowsazure.mediaservices

            //2. Get context
            var context = new CloudMediaContext(AccountName, AccountKey);

            //3. Get Streaming Asset
            var streamingAsset = (from a in context.Assets
                                  where a.Name == StreamingAssetName
                                  select a).FirstOrDefault();

            //3.1 Get Downloading Asset
            var downloadingAsset = (from a in context.Assets
                                    where a.Name == DownloadingAssetName
                                    select a).FirstOrDefault();

            //4. Create an access policy for a streaming asset
            var streamingAccessPolicy = context.AccessPolicies.Create("Access policy for " + StreamingAssetName, TimeSpan.FromDays(10), AccessPermissions.Read);

            //4.1 Create access policy for a downloading asset
            var downloadingAccessPolicy = context.AccessPolicies.Create("Access policy for " + DownloadingAssetName, TimeSpan.FromDays(10), AccessPermissions.Read);

            //5. Create a locator for a streaming asset
            var streamingLocator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, streamingAsset, streamingAccessPolicy);

            //5.1 Create a locator for a downloading asset
            var downloadingLocator = context.Locators.CreateSasLocator(downloadingAsset, streamingAccessPolicy);

            //6 Streaming info
            Console.WriteLine("Streaming Path: {0}n", streamingLocator.Path);
            Console.WriteLine("Streaming Type: {0}n", streamingLocator.Type);
            Console.WriteLine("Streaming ExpirationDateTime: {0}n", streamingLocator.ExpirationDateTime);
            Console.WriteLine("URL asset files:n");

            foreach (var manifest in streamingAsset.AssetFiles.Where(f => f.Name.EndsWith(".ism")))
            {
                Console.WriteLine("  {0}{1}/manifestn", streamingLocator.Path, manifest.Name);
            }

            Console.WriteLine();
            Console.WriteLine();

            //6.1 Downloading info
            Console.WriteLine("Downloading Path: {0}n", downloadingLocator.Path);
            Console.WriteLine("Downloading Type: {0}n", downloadingLocator.Type);
            Console.WriteLine("Downloading ExpirationDateTime: {0}n", downloadingLocator.ExpirationDateTime);
            Console.WriteLine("URL asset files:n");

            foreach (var file in downloadingAsset.AssetFiles.Where(f => f.Name.EndsWith(".mp4")))
            {
                Console.WriteLine("  {0}/{1}{2}n", downloadingLocator.BaseUri, file.Name, downloadingLocator.ContentAccessComponent);
            }

            Console.ReadLine();
        }
    }
}

When we expose our content, we must consider that there are several options to share it: streaming, as seen in the post about Dynamic Packaging, MP4 progressive download or just downloading content to the local machine. Therefore, in this example I’ve published two assets, streamingAsset and downloadingAsset, in order to have both publication types. The steps are almost the same:

  1. We need the account credentials and the name of the assets we want to publish.
  2. Install the windowsazure.mediaservices via Nuget.
  3. Recover the context of the account.
  4. Retrieve the assets. In this example we are getting through the name, but it is recommended to recover assets by Id, since the names can be repeated .
  5. When an asset is published is necessary to define an access policy with an expiration date and the type of access you want for the asset . In this case it is given to both read access for 10 days. Each asset can have up to 5 different access policies.
  6. The last step is the creation of a locator, which will help us to generate the final URL to the content. In the case of streaming we use context.Locators.CreateLocator, where we use the type of locator OnDemandOrigin , in addition to the asset and the access policy. For the second case, downloading content, use context.Locators.CreateSasLocator passing the asset and policy for this instance. From this moment the necessary values ​​will be generated for accessing to the content in both assets (also it will be reflected on the portal).
  7. To display the results, I use the console, where I show the path created, type of publication and the expiration date. In addition, for each of the examples, I use AssetFiles to create an individual URL for each file in the asset. For streaming the URL will be [PATH][FILE_NAME].ism/Manifest and for the SaS type will be [BASE_URI]/[FILE_NAME][CONTENT_ACCESS_COMPONENT]

The result:

Publish Assets Output

Hope this helps.

Happy weekend!