Test Driving Windows Azure Media Services

August 26, 2012 — Leave a comment

Recently Microsoft released Windows Azure Media Services preview, which essentially is a Platform as a Service that empowers developers to build workflows for the creation, management, and distribution of media.

This post is a retrospective of my first experience with this new service.


Getting Started

Getting to know the services I started to look for a video I could use for my test, so I grabbed the first Canon 7D I could find and headed out to make a short video. Canon records videos as MOV files of considerable size and quality so I thought this was the perfect candidate to test the format conversion and Smooth Streaming.

Once I got my video imported on my PC I rapidly started to get setup. Using the following instructions. I downloaded and installed the following packaged.

Windows Azure SDK 1.6 (November 2011)
Windows Azure SDK 1.7 (June 2012)
Windows Azure SDK on Windows 8
Windows Azure Media Services SDK for .NET
WCF Data Services 5.0 for OData v3

Then I created a project and referenced the following DLLs

Microsoft.Data.Edm.dll
Microsoft.Data.OData.dll
Microsoft.Data.Services.Client.dll
Microsoft.Data.Services.dll
System.Spatial.dll
Microsoft.WindowsAzure.StorageClient.dll
Microsoft.WindowsAzure.MediaServices.Client.dll

If you are using Visual Studio 2012 be sure to set the Target Framework setting to .NET Framework 4.

Ingesting Media

Looking at examples of the services’ API I pieced together this ModelCommand which allowed me to upload my MOV file by creating a new Unencrypted Asset.

public class CreateAssetModelCommand : IModelCommand<CloudMediaContext>
{
        private readonly string[] files;
        private readonly string primaryFile;
        private readonly CancellationTokenSource cancellationToken;
        Task<IAsset> task;

        public CreateAssetModelCommand(string[] files, string primaryFile)
        {
            this.files = files;
            this.primaryFile = primaryFile;
            cancellationToken = new CancellationTokenSource();
        }

        public void Apply(CloudMediaContext model)
        {
            task = model.Assets.CreateAsync(files, 
                                            primaryFile, 
                                            AssetCreationOptions.None, 
                                            cancellationToken.Token);
            task.ContinueWith(asset =>              {
                 var cmd = new CreateJobModelCommand(asset.Result);
                 cmd.Apply(model);
            });
        }

        public void Cancel()
        {
            cancellationToken.Cancel(false);
        }
}

This ModelCommand will allow us to create an Asset. An asset contains files that make up the media content. After creating and uploading an Asset I noticed that the Asset –> Files structure strongly resembled the

Blob Storage Container –> Blob structure.

Further investigation confirmed my intuition, the assets are stored in the storage account which I provided when I configured the Media Services instance. Using tools like visual studio I was able to browse my assets located in the storage account.

The dashboard found in the Management Portal shows storage consumption and other useful information.

Executing the above ModelCommand will result in creating the Asset and uploading the files to the storage account. I specified that I did not want the Asset to be encrypted and provided a cancelation token. Large files will be chunked and uploaded as blobk blobs. This will be done automatically by the CloudStorageClient used by the CloudMediaContext.

Once the upload is complete, the ModelCommand creates a new ModelCommand which will build and start a Job to convert and encode the Asset to Smooth Streaming for consumption by SilverLight.

Encoding & Format Conversion

I then set out to convert my MOV file to MP4 using the Windows Azure Media Encoder. This encoder lets you run encoding tasks using the Media Encoder. My plan was to then use the MP4 to Smooth Streams Task to convert my media assets from .mp4 to the smooth streaming format.

I rapidly hit a wall when I found out that MOV was not a supported format by the Windows Azure Media Encoder.  So I set out to find out what formats were supported.

 

Media Encoder Import Formats

Video Codecs

  • H.264 (Baseline, Main, and High Profiles)
  • MPEG-1
  • MPEG-2 (Simple and Main Profile)
  • MPEG-4 v2 (Simple Visual Profile and Advanced Simple Profile)
  • VC-1 (Simple, Main, and Advanced Profiles)
  • Windows Media Video (Simple, Main, and Advanced Profiles)
  • DV (DVC, DVHD, DVSD, DVSL)

Audio Codecs

  • AC-3 (Dolby Digital audio)
  • AAC (AAC-LC, HE-AAC v1 with AAC-LC core, and HE-AAC v2 with AAC-LC core)
  • MP3
  • Windows Media Audio (Windows Media Audio Standard, Windows Media Audio Professional, and Windows Media Audio Lossless)

File Format File Extensions

3GPP, 3GPP2

.3gp, .3g2, .3gp2

Advanced Systems Format (ASF)

.asf

Advanced Video Coding High Definition (AVCHD)

[MPEG-2 Transport Stream]

.mts, .m2ts

Audio-Video Interleaved (AVI)

.avi

AviSynth

.avs

Digital camcorder MPEG-2 (MOD)

.mod

Digital video (DV) camera file

.dv

DVD transport stream (TS) file

.ts

DVD video object (VOB) file

.vob

Expression Encoder Screen Capture Codec file

.xesc

MP4

.mp4

MPEG-1 System Stream

.mpeg, .mpg

MPEG-2 video file

.m2v

Smooth Streaming File Format (PIFF 1.3)

.ismv

Windows Media Video (WMV)

.wmv

File Format File Extensions

AC-3 (Dolby Digital) audio

.ac3

Audio Interchange File Format (AIFF)

.aiff

Broadcast Wave Format

.bwf

MP3 (MPEG-1 Audio Layer 3)

.mp3

MP4 audio

.m4A

MPEG-4 audio book

.m4b

WAVE file

.wav

Windows Media Audio

.wma

File Format File Extensions

Bitmap

.bmp

GIF, Animated GIF

.gif

JPEG

.jpeg, .jpg

PNG

.png

TIFF

.tif

WPF Canvas XAML

.xaml

Media Encoder Export Formats

File Format Video Codec Audio Codec

Windows Media (*.asf; *.wmv; *.wma)

VC-1 (Advanced, Main, and Simple Profiles)

WMA Standard, WMA Professional, WMA Voice, WMA Lossless

MP4 (*.mp4)

H.264 (High, Main, and Baseline Profiles)

AAC-LC, HE-AAC v1, HE-AAC v2

Smooth Streaming File Format (PIFF 1.3) (*.ismv; *.isma)

VC-1 (Advanced Profile)

H.264 (High, Main, and Baseline Profiles)

WMA Standard, WMA Professional

AAC-LC, HE-AAC v1, HE-AAC v2

Once I found this information, I started to hunt for a conversion application that would allow me to go from MOV to MP4 and proceeded to the conversion on my local machine. I deleted the previously created Asset and created a new one with my MP4 video.

The following code will find all locators for an Asset and it will revoke them. Trying to delete an Asset without revoking the locators will result in errors.

try
{
      var ls = context
                    .Locators
                    .Where(l => l.AssetId == SelectedAsset.Id)
                    .Select(l => l)
                    .ToList();

     ls.ForEach(l=> context.Locators.Revoke(l));

     context.Assets.Delete(SelectedAsset);
}
catch(Exception e)
{
    Debug.WriteLine(e.ToString());
}

The following ModelCommand is instantiated and Applied once the Asset files have been uploaded. The ModelCommand creates and starts a job that converts the MP4 to Smooth Streaming using the MP4 to Smooth Streams Task from the Media Processors made available by the Media Services.

Jobs are submitted to the Media Services  and the processing is deferred to Windows Azure.

public class CreateJobModelCommand : IModelCommand<CloudMediaContext>
{
    private readonly IAsset asset;
    IJob job;

    public CreateJobModelCommand(IAsset asset)
    {
        this.asset = asset;
    }

    public void Apply(CloudMediaContext model)
    {
        job = model.Jobs.Create("Encoding Job");
        // Get a media processor reference, and pass to it the name of the 
        // processor to use for the specific task. Use a method like the 
        // GetMediaProcessor method shown in this document.
        var processor = GetMediaProcessor("MP4 to Smooth Streams Task", model);

        // Create a task with the encoding details, using a configuration file.
        ITask task = job.Tasks.AddNew("Mp4 to Smooth Task",
            processor,
            Resources.MP4_to_Smooth_Streams,
            TaskCreationOptions.ProtectedConfiguration);
        // Specify the input asset to be encoded.
        task.InputMediaAssets.Add(asset);
        // Add an output asset to contain the results of the job.
        task.OutputMediaAssets.AddNew("Output " + asset.Name,
            true,
            AssetCreationOptions.None);

        // Launch the job. 
        job.Submit();
    }

    private IMediaProcessor GetMediaProcessor(string mediaProcessor,
                                              CloudMediaContext model)
    {
        // Query for a media processor to get a reference.
        var theProcessor =
            from p in model.MediaProcessors
            where p.Name == mediaProcessor
            select p;
        // Cast the reference to an IMediaprocessor.
        IMediaProcessor processor = theProcessor.First();

        if (processor == null)
        {
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                        "Unknown processor",
                                                        mediaProcessor));
        }
        return processor;
    }
}

The above code uses the task presets found below for the MP4 to Smooth Streaming conversion.

Jobs are used to specify and configure Tasks to be executed over Assets. The task presets for each Media Processor can be found below.

Windows Azure Media Encoder – Lets you run encoding tasks using the Media Encoder.

Task Preset Strings for Windows Azure Media Encoder

Task Preset for Thumbnail Generation

 

PlayReady Protection Task – Lets you encrypt media assets using PlayReady Protection.

Task Preset for Playready Protection

 

MP4 to Smooth Streams Task – Lets you convert media assets from .mp4 to smooth streaming format.

Task Preset for MP4 to Smooth Streams Conversion

 

Smooth Streams to HLS Task – Lets you convert media assets from smooth streaming to the Apple HTTP Live Streaming (HLS) format.

Task Preset for Smooth Streams to Apple HLS Conversion

Storage Decryption – Lets you decrypt media assets that were encrypted using storage encryption.

 

Content Protection

Since I did not have any requirements I did not explore this aspect of the workflow. This will be for a future blog post.

On-Demand Streaming

The following ModelQuery requests a Shared Access allowing the consumer to temporarily access files from the asset for 1 day. The resulting URI is used in a media player that can consume Smooth Streaming.

public class GetAssetStreamingUrl : IModelQuery<CloudMediaContext, string>
{
    private readonly IAsset selectedAsset;

    public GetAssetStreamingUrl(IAsset selectedAsset)
    {
        this.selectedAsset = selectedAsset;
    }

    public string Execute(CloudMediaContext model)
    {
        // Get a reference to the manifest file from the collection 
        // of streaming files in the asset. 
        var theManifest =
            from f in selectedAsset.Files
            where f.Name.EndsWith(".ism")
            select f;
        // Cast the reference to a true IFileInfo type. 
        var manifestFile = theManifest.FirstOrDefault();

        if (manifestFile != null)
        {
            // Create an 1-day readonly access policy. 
            var streamingPolicy = model
                                    .AccessPolicies
                                    .Create("Streaming policy",
                                        TimeSpan.FromDays(1),
                                        AccessPermissions.Read);

            // Create the origin locator. Set the start time as 5 minutes 
            // before the present so that the locator can be 
            // accessed immediately 
            // if there is clock skew between the client and server.
            var originLocator = model
                                .Locators
                                .CreateOriginLocator(selectedAsset,
                                    streamingPolicy,
                                    DateTime.UtcNow.AddMinutes(-5));

            // Create a full URL to the manifest file. Use this for playback
            // in streaming media clients. 
            string urlForClientStreaming = originLocator.Path 
                                         + manifestFile.Name 
                                         + "/manifest";

            return urlForClientStreaming;
        }
        return string.Empty;
    }
}

Wrapping it up

After playing around with the services for a while, I truly see a huge potential and tons of possibilities! The Windows Azure Media Services give you control over your media asset distribution workflow. Empowering you to provide scalable and reliable media streaming sources for your customers.

I can’t wait for these services to be released.

No Comments

Be the first to start the conversation!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s