Monday 30 July 2018

Microsoft Azure Media Service – Encoding & Indexing Process using C#.Net – Part 2


As per continue thread on encoding and indexing process via Azure media service, in this part I would share technical implementation pf those steps via source code.

We need to Install the Azure SDK for an additional set of templates and tools which help you access even more cloud resources and services to improve your Azure development experience directly from Visual Studio. Also you can install library using NuGet packages.

Below are the some of namespace which I have import for this implementation:

using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.MediaServices.Client.ContentKeyAuthorization;
using Microsoft.WindowsAzure.MediaServices.Client.DynamicEncryption;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

As mentioned above - we are using Azure storage and media service class library, first of all we wold create instance of storage account’s container blob client to pull the Media files.  

CloudQueueClient AzureQueueClient;
CloudQueue AzureCloudQueue;
CloudQueueMessage AzureQueueMessage;

public ProcessorService()
      {
            var tokenCredentials = new AzureAdTokenCredentials(AppConfiguration.AADTenantDomain,
                new AzureAdClientSymmetricKey(AppConfiguration.ClientId, AppConfiguration.ClientSecret),
                AzureEnvironments.AzureCloudEnvironment);
            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);
            context = new CloudMediaContext(new Uri(AppConfiguration.RESTAPIEndpoint), tokenProvider);

            sourceStorageAccount = new CloudStorageAccount(new StorageCredentials(AppConfiguration.SourceStorageAccountName, AppConfiguration.SourceStorageAccountKey), true);
            amsStorageAccount = new CloudStorageAccount(new StorageCredentials(AppConfiguration.AMSStorageAccountName, AppConfiguration.AMSStorageAccountKey), true);
            issuer = AppConfiguration.Issuer;
            Audience = AppConfiguration.Audience;

            AzureQueueClient = sourceStorageAccount.CreateCloudQueueClient();
        }

Get the respective blob file :

CloudBlockBlob blob = (CloudBlockBlob)sourceFile;
Copy blob file to Azure media service storage container file.

var amsFile = amsAssetContainer.GetBlockBlobReference(strFilename);

            if (!amsFile.Exists())
            {
                amsFile.StartCopyAsync(new Uri(sourceFile.Uri.AbsoluteUri + signature));
                 while (true)
                {
                    amsFile.FetchAttributes();
                    if (amsFile.CopyState.Status != CopyStatus.Pending)
                    {
                        break;
                    }
                    //It's still not completed. So wait for some time.
                    System.Threading.Thread.Sleep(1000);
                }
            }

After copy of blob file need to initiate encoding process job

public IAsset EncodeToAdaptiveBitrateMP4Set(IAsset asset)
        {
            // Declare a new job.
            var job = context.Jobs.Create(string.Format("Media Encoder Standard processing of {0}", asset.Name));

            var processor = GetLatestMediaProcessorByName("Media Encoder Standard");

            // In this case "Adaptive Streaming" preset is used.
            var task = job.Tasks.AddNew(string.Format("Media Encoder Standard processing of {0}", asset.Name),
                processor,
                "Adaptive Streaming",
                TaskOptions.None);

            task.Priority = 100;
            task.InputAssets.Add(asset);
            task.OutputAssets.AddNew(string.Format("{0} - Media Encoder Standard encoded", asset.Name),
                AssetCreationOptions.None);

            job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged);
            job.Submit();
            job.GetExecutionProgressTask(CancellationToken.None).Wait();

            return job.OutputMediaAssets[0];
        }

After continue monitor of job state – finally we would need to publish URL

  private string GetStreamingOriginLocator(IAsset asset)
        {

             var assetFile = asset.AssetFiles.Where(f => f.Name.ToLower().
                                        EndsWith(".ism")).
                                        FirstOrDefault();

            IAccessPolicy policy = context.AccessPolicies.Create("Streaming policy",
                TimeSpan.FromDays(1825),
                AccessPermissions.Read);

            // Create a locator to the streaming content on an origin.
            ILocator originLocator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset,
                policy,
                DateTime.UtcNow.AddMinutes(-5));

            // Create a URL to the manifest file.
            return originLocator.Path + assetFile.Name;
        }

You would get streaming locator which would be used in Media play for streaming  content.

In the same manner – After Encoding you should initiate the Indexing process job like below

public IAsset RunIndexingJob(IAsset asset)
        {
            // Declare a new job.
            IJob job = context.Jobs.Create(string.Format("Media Indexing processing of {0}", asset.Name));

            // grab an instance of Azure Media Indexer and run a job
            IMediaProcessor indexer = GetLatestMediaProcessorByName("Azure Media Indexer");

            string title = asset.Name;
            title = System.Text.RegularExpressions.Regex.Replace(title, @"[^\w\.@-]", " ");
            string configuration = "<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration version=\"2.0\"><input><metadata key=\"title\" value=\"@title\" /><metadata key=\"description\" value=\"\" /></input><settings></settings><features><feature name=\"ASR\"><settings><add key=\"Language\" value=\"English\"/><add key=\"CaptionFormats\" value=\"ttml; sami; webvtt\"/><add key=\"GenerateAIB\" value =\"true\" /><add key=\"GenerateKeywords\" value =\"true\" /></settings></feature></features></configuration>";
            configuration = configuration.Replace("@title", title);
            ITask task = job.Tasks.AddNew(string.Format("Media Indexing processing of {0}", asset.Name),
                indexer,
                configuration,
                TaskOptions.None);

            task.Priority = 100;

            // Specify the input asset to be encoded.
            task.InputAssets.Add(asset);
            task.OutputAssets.AddNew(string.Format("{0} - Media Indexed file", asset.Name), AssetCreationOptions.None);

            job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged);
            job.Submit();
            job.GetExecutionProgressTask(CancellationToken.None).Wait();

            return job.OutputMediaAssets[0];
        }

After completion of indexing process – you would able to download files.

static void DownloadAsset(IAsset asset, string outputDirectory)
        {
            try
            {
                foreach (IAssetFile file in asset.AssetFiles)
                {
                    file.Download(Path.Combine(outputDirectory, file.Name));
                }
            }
            catch (Exception ex)
            {
                 throw ex;
            }
         }


An indexing job can generate the following outputs:

  1.  Closed caption files in the following formats: SAMI, TTML, and WebVTT.
  2.  Keyword file (XML). 
  3.  Audio indexing blob file (AIB) for use with SQL server.







So above are the process of encoding and indexing of media file using C#.NET, if you would have any queries and please comment below, for more in-depth information kindly follow Microsoft MSDN site. - https://docs.microsoft.com/en-us/azure/media-services/



Thank you!


No comments:

Post a Comment

Xamarin - Cross Platform Mobile Development

Xamarin - Cross Platform Mobile Development Xamarin is one of the most popular cross-platform frameworks at the moment. Xamarin devel...