How to Build Customized Media Workflows Using the Media Services .NET SDK - Part II

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.
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); Console.ReadKey(); Console.ReadKey(); }
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.Upload(inputFilePath); assetFile.MimeType = "video/mp4"; assetFile.Update(); 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"; // http://msdn.microsoft.com/en-us/library/windowsazure/jj129582.aspx#H264Encoding 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.InputAssets.Add(inputAsset); encodeTask.OutputAssets.AddNew(inputAsset.Name + " as " + encodingPreset, AssetCreationOptions.None); job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged); job.Submit(); job.GetExecutionProgressTask(CancellationToken.None).Wait(); 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, TimeSpan.FromDays(daysForWhichStreamingUrlIsActive), 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 ]//Namespace