Introduction to Dynamic Packaging with Windows Azure Media Services

Download this episode

Download Video


This presentation introduces the a Windows Azure Media Services feature available via the on-demand streaming origins called "Dynamic Packaging". You'll hear an overview of the feature, and go into the details of writing some simple code to use it.




Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • User profile image

      using Microsoft.WindowsAzure.MediaServices.Client;
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading;
      namespace ConsoleApplication1
          class Program
              static void Main(string[] args)
                  // Create .Net console app
                  // Set project properties to use the full .Net Framework (not Client Profile)
                  // With NuGet Package Manager, install windowsazure.mediaservices
                  // add: using Microsoft.WindowsAzure.MediaServices.Client; 
                  var context = new CloudMediaContext("yourwamsaccountname", "H6Gd...wamskey...df4=");
                  string inputAssetId = CreateAssetAndUploadFile(context);
                  IJob job = EncodeToMultiBitrateMp4(context, inputAssetId);
                  var mp4Asset = job.OutputMediaAssets.FirstOrDefault();
                  string mp4StreamingUrl = GetDynamicStreamingUrl(context, mp4Asset.Id, LocatorType.Sas);
                  string smoothStreamingUrl = GetDynamicStreamingUrl(context, mp4Asset.Id, LocatorType.OnDemandOrigin);
                  string hlsStreamingUrl = smoothStreamingUrl + "(format=m3u8-aapl)";
                  Console.WriteLine("\n Mp4 Url:    \n" + mp4StreamingUrl);
                  Console.WriteLine("\n Smooth Url: \n" + smoothStreamingUrl);
                  Console.WriteLine("\n HLS Url:    \n" + hlsStreamingUrl);


              private static string CreateAssetAndUploadFile(CloudMediaContext context)
                  var inputFilePath = @"C:\demo\bing_social_search.mp4";
                  var assetName = Path.GetFileNameWithoutExtension(inputFilePath);
                  var inputAsset = context.Assets.Create(assetName, AssetCreationOptions.None);
                  var assetFile = inputAsset.AssetFiles.Create(Path.GetFileName(inputFilePath));
                  assetFile.UploadProgressChanged += new EventHandler<UploadProgressChangedEventArgs>(assetFile_UploadProgressChanged);
                  assetFile.MimeType = "video/mp4";
                  return inputAsset.Id;
              static void assetFile_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
                  Console.WriteLine(string.Format("{0}   Progress: {1:0}   Time: {2}", ((IAssetFile)sender).Name, e.Progress, DateTime.UtcNow.ToString(@"yyyy_M_d__hh_mm_ss")));


              private static IJob EncodeToMultiBitrateMp4(CloudMediaContext context, string inputAssetId)
                  var inputAsset = context.Assets.Where(a => a.Id == inputAssetId).FirstOrDefault();
                  if (inputAsset == null)
                      throw new ArgumentException("Could not find assetId: " + inputAssetId);
                  var encodingPreset = "H264 Adaptive Bitrate MP4 Set SD 16x9"; //
                  IJob job = context.Jobs.Create("Encoding " + inputAsset.Name + " to " + encodingPreset);
                  IMediaProcessor latestWameMediaProcessor = (from p in context.MediaProcessors where p.Name == "Windows Azure Media Encoder" select p).ToList()
                                                                               .OrderBy(wame => new Version(wame.Version)).LastOrDefault();
                  ITask encodeTask = job.Tasks.AddNew("Encoding", latestWameMediaProcessor, encodingPreset, TaskOptions.None);
                  encodeTask.OutputAssets.AddNew(inputAsset.Name + " as " + encodingPreset, AssetCreationOptions.None);
                  job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged);
                  return job;
              static void JobStateChanged(object sender, JobStateChangedEventArgs e)
                  Console.WriteLine(string.Format("{0}\n  State: {1}\n  Time: {2}\n\n",
                                                 ((IJob)sender).Name, e.CurrentState, DateTime.UtcNow.ToString(@"yyyy_M_d__hh_mm_ss")));


              private static string GetDynamicStreamingUrl(CloudMediaContext context, string outputAssetId, LocatorType type)
                  var daysForWhichStreamingUrlIsActive = 365;
                  var outputAsset = context.Assets.Where(a => a.Id == outputAssetId).FirstOrDefault();
                  var accessPolicy = context.AccessPolicies.Create(outputAsset.Name,
                                                                   AccessPermissions.Read | AccessPermissions.List);
                  var assetFiles = outputAsset.AssetFiles.ToList();
                  if (type == LocatorType.OnDemandOrigin)
                      var assetFile = assetFiles.Where(f => f.Name.ToLower().EndsWith(".ism")).FirstOrDefault();
                      if (assetFile != null)
                          var locator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, outputAsset, accessPolicy);
                          Uri smoothUri = new Uri(locator.Path + assetFile.Name + "/manifest");
                          return smoothUri.ToString();
                  if (type == LocatorType.Sas)
                      var mp4Files = assetFiles.Where(f => f.Name.ToLower().EndsWith(".mp4")).ToList();
                      var assetFile = mp4Files.OrderBy(f => f.ContentFileSize).LastOrDefault(); //Get Largest File
                      if (assetFile != null)
                          var locator = context.Locators.CreateLocator(LocatorType.Sas, outputAsset, accessPolicy);
                          var mp4Uri = new UriBuilder(locator.Path);
                          mp4Uri.Path += "/" + assetFile.Name;
                          return mp4Uri.ToString();
                  return string.Empty;
        }//close out class


    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to send us feedback you can Contact Us.