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!


Thursday, 28 June 2018

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

I would like to share development experience during the process of converting media encoding and transcribing using Azure media service. There are many resources available on Microsoft and other sites still, I would try my best to explain the process via practical scenario so that anyone would understand easy by referring to this blog.

There are many media industries who have lots of media(audio/video) libraries, those files are large may be too large to deliver content over the Internet for his customer. To deliver smooth media over the internet it requires encoding process. Encoding is a phenomenon which compresses video and audio by using Azure Media Services and publish over the internet for on demand playlist.

Below are the pre-requirement to process before development :

  • IDE -Visual Studio 2015/2017
  • C#.NET
  • Azure SDK
  • Azure Media Service
  • Azure Storage Account

Azure Media Services Encoder and Indexing Manual Process through Azure web portal:

  1.  Log in to the Azure portal and open Media Service and click on Assets – Here you can click on Upload button and upload the video file those you want to encoding and streaming over the internet.
  2. After successfully uploaded video file – you can select upload file and click on top bar Encode button and select encoding preset information – hit the Start button to initiate the process.
  3. After initiating process – you can review job progress on click at Job tab
  4. After completion of encoding job, it would have processed output Multi-bitrate output files.
  5. Publish the encoded content – and select the Locator URL to Play the video over the Media player. Sample Azure Media Player
  6. For Indexing/Transcribing those video file select Analyze button and create Indexing job for closed captioning files.
  7. Once click on create it would also initiate job in background after finished status - it would generate output files like SAMI, TTML, and WebVTT output files.
  8. Published and generate URL and attach *.VTT file along with Media Player so that content would show on a player during streaming.

So that’s all about the manual process for encoding and indexing process of media files !!!

I would request you to follow the steps and do manual process and I will create a new post in Part 2 of this blog with dynamic operation using C#.NET.

Stay Tuned!!!!

Friday, 25 May 2018

Power BI - Dashboard Usage


Power BI is a Microsft business analytics tool to analyze data and share insights to your application, it provides a different view for business and CxO users with their most important key information at one place, updated in real-time and available in all other devices. 

There are two version of Power BI usage:
1. Desktop version Power BI
2. Web Version  Power BI Online

Both of them have their capabilities based on the platform additionally, the desktop contains a whole suite of tools to create models, to Build models and create visuals and Web would also provide to create visuals and Sharing options.

Power BI - Desktop:

We have used Power BI desktop version to implement Dashboard for the one of our Web Application. It is easy and to built and publish to your app based on your customized view.

There are so many data source provide by Power BI - for more detail of supported source are here - https://docs.microsoft.com/en-us/power-bi/desktop-data-sources


Configuration Steps with Data Source as SQL Database:

Installed and open Power BI Desktop - with an authorized credential.
Select the data source that you needs to show on the dashboard for a web application.



Import the Visual based on your requirement and drag into the main panel and select the dataset.

below is the sample configured visual dashboard with sample dataset.


After completion of visual and setting up data set - Publish the Dashboard for live usage and it would be ready to integrate for your web application.



To keep dashboard and report up-to-date with your on-premises data source - There is a gateway to set up for keep source as refreshing on the certain scheduling interval.

Power BI - Benefits:

  1. Any time any location and any device access to the dashboard.
  2. Ability to fetch progress of current Task, Client, and resources progress.
  3. Ability to Share – User can share with anyone from anywhere in the world.
  4. Increased visibility and getting a more business plan without having to look for manual effort.
I hope above information will help you guys to set up Power BI basics and for more information please review Microsoft Power BI reference site.

Thursday, 26 April 2018

Namely API - Integration with .NET Web application


Namely is an all in one human resource information system. Its offer HRIS, payroll, benefits administration & management, and performance reviews.

If any organization have the central system of namely that contains all employee information, there is a situation where the organization has a different application that requires accessing namely employee’s data. So that this blog is more specific to how to integrate existing Namely Employee data to other software.

Prerequisite:

Authorize namely software with Administrator access rights.

Authorization with Namely System:

In order to use the Namely API, the user must have permission within the system to generate either an API Client or Access Token object.




Once you do, you will see a form to create an API client and/or a form to create an Access Token, depending on which permissions you have. There are two ways to integrate one is API Client and other is Access Token object.

Access Token object:

Creating a Permanent Access Token is a way to bypass the OAuth flow. A Permanent Access Token is significantly longer lived, lasting 2 years. Anyone who has this Access Token is able to access Namely with it alone, which represents a significant security risk. While this access method may be convenient for your purposes.

Permanent Access Tokens:

If you decide to use Permanent Access Tokens, the interface is located alongside API Client creation and will be visible with the proper permission. Please consult your company's Namely or Namely Client Success Representative to have your permissions properly set up.

Namely also provides an interface to create long-lived Access Tokens. While these can be useful for server processes, we urge you to be cautious. Anyone with access to the Access Token can access your system. Avoid placing such tokens in shared code bases, etc.

Namely API request:

You need to include your Access Token in your request headers; you should place them in the "Authorization" element in your headers in the format 'Bearer [Access Token]'.

Below are the code snippets from C# - it passes two parameter – Namely API URL & Authentication Token.

 public ApiResult<bool> SyncNamelyProfiles(long userId)
        {
            NamelyProfileEntity namelyProfileEntity = new NamelyProfileEntity();
            var url = AppConfiguration.NamelyApiURL + "profiles";
            var pageNumber = 1;
            namelyProfileEntity = GetNamelyProfilesByPagination(AppConfiguration.NamelyApiURL, AppConfiguration.NamelyBearerAuthenticationToken, AppConfiguration.NamelyPageSize, pageNumber);
            while (namelyProfileEntity.meta.Count > (AppConfiguration.NamelyPageSize * pageNumber))
            {
                pageNumber = pageNumber + 1;
                namelyProfileEntity.Profiles.AddRange((GetNamelyProfilesByPagination(AppConfiguration.NamelyApiURL, AppConfiguration.NamelyBearerAuthenticationToken, AppConfiguration.NamelyPageSize, pageNumber).Profiles));
            }
            var result = iNamely.SyncNamelyProfiles(namelyProfileEntity, userId);
            return HttpStatusCode.OK.SuccessResponse<bool>(result);
        }


        private NamelyProfileEntity GetNamelyProfilesByPagination(string namelyURL, string token, int pageSize, int pageNumber)
        {
            var url = namelyURL + "profiles";
            var queryString = "?" + "per_page=" + pageSize + "&page=" + pageNumber;
            var client = new RestClient(url + queryString);
            var request = new RestRequest(Method.GET);
            request.AddHeader("authorization", "Bearer " + token);
            request.AddParameter("undefined", "{}", ParameterType.RequestBody);
            IRestResponse response = client.Execute(request);
            var result = Converter.Deserialize<NamelyProfileEntity>(response.Content);
            return result;
        }


It will return employee basic information and store it in individual database/store for an organization level different application usages.

Monday, 5 March 2018

Automation Process - Azure Storage Account To Azure Media Service Encoding Process




Today, I would like to share detail on automation process that we implemented in our recent development work.

I split blog in three division so that it would help for better understanding. 

Problem Statement:

We had implemented Cloud service for existing library files to process Azure media encoding and transcribing process so that it processed all the thousands of files successfully.

Now- Based on new requirement end user would upload files from the web application and that newly uploaded files would store in Azure Storage account.

We have to reuse existing cloud service source code logic so that it would process new uploaded media file for encoding and transcribing job.


The solution we design:

As we approach Azure function and mediator to communicate cloud service, new media upload.
Below is the high-level cross-functional diagram.



Actual Implementation: 

Azure functions is a solution for easily running small pieces of code in the cloud. we can write just the code you need for the problem at hand, without worrying about a whole application or the infrastructure to run it. 

We have implemented an Azure function in a language of choice, such as C#, F#, Node.js, Java, or PHP. 

We created in C# as per below code snippet so that once new blob upload from web to storage account it would auto trigger and send a message to blob queue.

#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Queue;

public static void Run(CloudBlockBlob myBlob, string name, ICollector<string> blobQueueItem, TraceWriter log)
{
log.Info($"C# Blob trigger function Processed blob\n Name:{name} \n URI: {myBlob.Uri} ");
blobQueueItem.Add(myBlob.Uri.ToString());
}


On other ends Cloud, service would de-queue message and send new uploaded assets to process encoding and transcribing service.


 CloudBlobClient sourceCloudBlobClient = sourceStorageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = sourceCloudBlobClient.GetContainerReference(AppConfiguration.SourceBlobContainerName);
CloudBlobClient amsCloudBlobClient = amsStorageAccount.CreateCloudBlobClient();

 CloudQueue AzureCloudQueue = AzureQueueClient.GetQueueReference(AppConfiguration.blobqueuename);
 var azureQueueMessageList = AzureCloudQueue.GetMessages();


I request you to share your thoughts on the same and I would really appreciate if you could provide your valuable feedback.

Thanks!!! 

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...