Saturday, July 30, 2016

C#: EditorBrowsabilityAttribute and hiding Methods, Properties and Field from IntelliSense

The .NET Framework includes the System.ComponentModel namespace's EditorBrowsableAttribute which allows the programmable elements to be used in an application but to be hidden from IntelliSense. Why expose a method (or any programmable element) as public but hide it from IntelliSense? If the method has been deprecated then it makes sense to allow it to be used in applications but at the same time to hide it from developers. When the method does not show up in IntelliSense courtesy of EditorBrowsableAttribute, the method is less likely to be used by developers when writing applications.

An example of a class garnishing programmable elements with the EditorBrowsableAttribute attribute is as follows:

using System.ComponentModel;

namespace AnyAssembly
{
    public class PoliticsAreBoring
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static short DonaldTrump { get; set; }

        [EditorBrowsable(EditorBrowsableState.Never)]
        public static short HillaryClinton { get; set; }

        public static long AlanTuring { get; set; }

        public static long AdmiralGraceHopper { get; set; }
    }
}

The properties DonaldTrump and HillaryClinton of the PoliticsAreBoring class are decorate with the EditorBrowsableAttribute attribute. The value of EditorBrowsableState.Never is passed to the constructor of EditorBrowsableAttribute. When the class, PoliticsAreBoring, is referenced by another application the IntelliSense for PoliticsAreBoring are as follows:


Notice in the previous screenshot that the properties DonaldTrump and HillaryClinton are not listed by IntelliSense even though they are public static members of their class.. The PoliticsAreBoring class resides in the AnyAssembly.dll assembly. In order for IntelliSense not to see properties decorated with [EditorBrowsable(EditorBrowsableState.Never)] the assembly must not be part of a project in the current solution. In the screenshot below, AnyAssembly.dll is a file residing on disk and is not a project in the solution: 


If the AnyAssembly project is added to the solution, IntelliSense show the properties decorated with [EditorBrowsable(EditorBrowsableState.Never)]. An example of this is as follows:


IntelliSense shows all the properties which is convenient when developing the AnyAssembly assembly. When the assembly is used without a project (say released as an SDK) then all programmable entities decorated with [EditorBrowsable(EditorBrowsableState.Never)] are not visible but can be used if simply typed into the source code. 

The EditorBrowsableAttribute attribute can be used to decorate classes, structures, constructors, fields, methods, properties, events, etc. 



Sunday, July 24, 2016

Visual Studio Installer Projects: Installing PDFs and other Content with an Install Project

As a developer I get dragged into the dreaded installer on occasion -- I'd rather be up to my elbows in Azure Web Services and Azure SQL. I was faced with an interesting problem for a client. Their WPF desktop application needed to display PDFs. To facilitate this the PDFs had to be added to the applications installer.

The solution associated with this project was ASNACalculatorMaster. This solution contained a WFP application, ASNACalculator, and an installer project, ASNACalculatorSetup:



The first step to include PDFs files in the WPF project was to create folder in which store. This is not required but it is simply part of good project organization. To do this you:

1) Right click on the project (such ASNACalculator above) and select Add | New Folder from the context menu (see below):


2) Once new folder is clicked a new editable folder is added to the project:


3) Change the name of the NewFolder to the desired folder name in which to store the content files (PDFs for this excample):



The content folder for this example is DataSheets.

Adding files is like adding file to any other folder. The files selected below are the files to to copy to the ASNACalculator project's DataSheets folder:


The infamous CTRL-C was use to selected the files above. After this navigate to Visual Studio's Solution Explorer and right click on the the DataSheets folder inside of ASNACalculator project:


Note in the previous screenshot that the Paste option is enabled. Selecting Paste will paste the files into the DataSheets folder:



At this pointed Visual Studio does not know how interpret the PDF files. They are not C# files so there is no way to build the files. To remedy this, select all of the PDF files in the DataSheets folder:


Right click on the folders thus displaying the context menu associated with the PDFs files in the project:


From the context menu select the Properties menu items. This displays the properties of all the selected files:


Under properties set Build Action to Content and set Copy to Output Directory to Copy if newer. An example of this is shown below:


The ASNACalculator project now understands that the PDFs are considered to be content of the project and should be copied into the build folder during a build. The PDF files in the build directory will be updated if newer files are placed DataSheets folder.

It is important to recognize that Visual Studio does not copy the PDFs file directly into the output directory. Instead Visual Studio copies the DataSheets folder including all the PDF files into the output directory (as shown below where the DataSheets folder is contained the Release folder of the build)::


At this point the WPF project, ASNACalculator, interprets the PDFs file as content. Now the setup project, ASNACalculatorSetup, needs to be changed to include content as part of the installer. This is achieved by right clicking on the installer project within Solution Explorer:


From the context menu show above select Project Output:


Selecting the Project Output menu items displays the Add Project Output Group show above. From this dialog select Content Files (shown above) and click on OK. Once OK is clicked from this dialog, the ASNACalculatorSetup appears as follows within Solution Explorer:


Notice above that the ASNACalculatorSetup project now contains an entry, Content Files from ASNA Calculator (Active). This means the PDFs (the conent) are included in the installer.

When installed the PDF files will be placed in DataSheets folder below the folder in which the ASNCalculator.exe is installed. An example of this is as follows:





Saturday, July 23, 2016

Example of my work: DYMO Stamps Online

I had to send a former colleague a message so I looked him up on LinkedIn. On his LinkedIn profile I found link to PC Magazine review of code we had jointly developed: DYMO Stamps Online. I developed the underlying Web Service and he developed the front-end. 

The contents of the review are as follows (just in case PC Magazine changes the links)  and of course hearty thanks to the author (M. David Stone of PC Magazine, "DYMO Stamps Online," October 18, 2012):






Saturday, July 2, 2016

Azure: Using Media Services to deliver HLS streams for consumption by IOS AV Player

Overview

A friend approached me with a problem. He was developing software for a school where instructors at the school needed to create instructional videos (short lessons to help students practice their English skills). These videos needed to be uploaded to a server/service/the cloud and made available to an IOS application used by the students.

I knew that we had two clear options:
  1. Amazon Web Services (AWS): Cloud Front and Elastic Transcoder 
  2. Azure: Media Services and potentially Content Delivery Network (CDN)

The plan was that he would attack the problem using AWS and I would attack the problem using Azure. We would first solve the problem using a manual process in my case Azure web-based management portal (https://portal.azure.com/). Once an end-to-end solution was in place, each manual step could be automated using the available RESTful APIs exposed by the cloud service selected.

The steps that ultimately needed to occur in order to develop proof-of-concept (POC) were:
  1. Upload the video
  2. Encode the video that supported a multi-bit format suitable for streaming and suitable for consumption using IOS AV Player
  3. Publish the encoded video so it could be displayed by IOS AV Player
This post will cover how to use Azure's management portal in order to perform the tasks outlined above. The programmatic steps to automate the processing using Azure's REST-based web services will be addressed in a future post or posts.

Create an Azure Media Service Instance

In order to achieve the goals of this post, a developer should have access to a Windows Azure and should login into the Azure portal at portal.azure.com:


A Media Services instance needs to be created so in the upper left corner click on the New button:

Clicking on New displays the following:


Under the categories displayed, select Media + CDN:


Click on Media Services to create a location where to store video (step 1 of our POC task), encode video (step 2) and stream video (step 3). Clicking on the Media Services button which display a UI blade in which a Media Service resource can be created:


The Media Service create blade takes a name and a resource group. The Media Service name is set to devschool01 below. The Media Service name is used in the URI used by the client that will ultimately consume media streams. For this reason the dev prefix was added because the Azure environment configured is for the POC and is not a production environment.  It is important to note that Azure resource names must be a combination of numbers and lower case letters. This is why the Media Service was named devschool01 not DevSchool01 (see below):


In the above screenshot of the create Media Service blade a resource group is specified. This was set to schools as all resources associated with this resource group will be part of the school video project. The location is set to West US (where the developers lived). When a production environment is created the location will be set to East Asia (where the school is located).

Storage Account was clicked above so a new Storage Account could be associated with the Media service being created. A Media Service instance does not actually store videos. A Media Service instance stores the metadata describing the videos which are stored within storage account. This storage account provides the blob storage used to store the assets associated with the Media Service instance.

The Choose storage account blade is show above an in addition to choosing a storage account, a storage account can be created.



When Create new is selected under Choose storage account, blade is created named Create storage account (see below) and in this case the storage can be called schools01:


Click OK to create the storage account. This results in the following being displayed:


Click on Create to create the Media Service instance with the newly created storage account, schools01. Once the Media Service resource is created, the portal returns to the Dashboard screen as shown below:


Clicking on All resources (upper left) displays all resource associated with the Azure account:


When All resources is clicked the following is displayed:



When all resources is displayed there is no Media Service resource named "devschool01" displayed. This is remedied by clicking the Refresh button:


Once refresh is selected the following is displayed with respect to "all resources":


The Media Service, devschool01, is displayed following the clicking of refresh.

Upload Video to Stream

A video, 10SecondSample.mov,  was created on an iPhone. To upload this file, login to Azure and navigate so all resource are displayed including the previously created Media Service, devschool01:


Click on the devschool01 Media Service in order to open the blades used to manage this resource:



From the right side under the MEDIA SERVICES category is an Assets button:



Click on the Assets button in order to display the blade used to manage the assets associated with the devschool01 Media Service. The Assets management blade is as follows:



On the Assets blade there is an Upload button at the top of the blade:



Click on the Upload button to display a blade used to upload file:



Click on the folder icon next to "select a file" in order to display a select file dialog. This will allow for a file on disk to be selected which will subsequently be uploaded as an asset of the devschool01 Media Service.

Once a file is selected the Upload a video asset blade appears as follows:


Under the file name text box is a progress bar where above the green indicates the file is half uploaded. Once a file is uploaded completely the progress bar is completely green as shown below:


When the mouse cursor hovers over the ! information icon, the information associated with the icon is displayed. Shown above the information icon in the previous screenshot is the message "File upload completed."

There is an X in the upper right corner of the Upload a video asset blade. Clicking on the this X closes the blade displaying the assets screen.

The video uploaded file is considered to be the master copy or a mezzanine file. That is just the nomenclature used by media services whether Azure, AWS or some other media environment.

Dynamic Content

Before the uploaded mezzanine file can be stream it needs to be encoded into a format suitable fore streaming. The idea is that that the encoded file should be able to support multiple display formats and multiple display devices (XBox, IOS, Andriod, etc.). The video file needs to be converted into a form a format the supports dynamic content.

Before demonstrating encoding dynamic content should be understood. A fanatic write up on dynamic content can be found at https://azure.microsoft.com/en-us/documentation/articles/media-services-dynamic-packaging-overview.

The remainder of this section on dynamic content contains excerpts from the link above because frankly it is a stellar write-up:


Encoding the Media File

In order to encode the mezzanine file for an asset it should be selected under the Assets blade:


Clicking on the file 10SecondSample.MOV file under Assets displays the blade for managing the 10SecondSample.Mov file which is as follows:


At the top of the blade is the Encode button:


Clicking on the Encode button displays the Encode an asset blade as shown below:


Clicking on the Encoding presets displays a list of candidate encoding formats (see below):



From the list of Encoding presets select the H264 Multiple Bitrate 1080p. After this selection the Encode an asset blade appears as follows:



Clicking on the Create button at the bottom of the blade starts the encoding process. A message will be displayed in the upper right corner of the screen indicating the encoding job is being added and later a message will display encoding has been completed.



At this stage of the project a media service exists, a file has been uploaded into the media service and this file has been encoded in a format suitable to streaming including being suitable for consumption by IOS AV Player.

Alarms

While setting up a Media Service instance two background jobs have been launched. The first was when the video file was uploaded. The second was when the was encoded. Messages related to such activities can be seen by clicking on the bell (the alarm) at the top of the Azzure portal. Clicking on the alarm icon is demonstrated below:


Publishing a Video

A video cannot be streamed until it is published. To publish video start at the screen that lists all the assets associated with a Media Service instance:



Slick on the video just encode, 10SecondSample.Mov - Media Encoder Standard encode, which is the video to publish:


From buttons above the blade used to manage the 10SecondSample.Mov - Media Encoder Standard encode, assett, select the Publish button which looks as follows:




Clicking on the Publish button display the Publish the asset blade:



On the Publish the asset blade are controls that allow the start and end date for publishing within a specified date rang. Once the settings on the Publish the asset blade hve been set click on Add. In order to see the progress of the Publish action, click on the Alarm icon which displays the following:


The state of the publishing is shown above is "Updating StreamingEndPoint ..." After the asset is published, the blade used to manage asset (see below) will contain a URL under Published URLs:



Clicking to the right of the URL will copy the URL. An example of the URL is as follows:

http://devschool01.streaming.mediaservices.windows.net/1adf84ef-530e-422b-aeae-f566bc44ac7d/10SecondSample.ism/manifest

The URL above is manifest file listing all encoding formats. A client could access this manifest file and determine the best available video format which to stream based on the client's screen resolution and internet connection speed.

Clicking inside the URL text box will display the Locator details blade (see below to the right):


Click on the icon at the end of the HLS(v4) URL copies the following link:

http://devschool01.streaming.mediaservices.windows.net/1adf84ef-530e-422b-aeae-f566bc44ac7d/10SecondSample.ism/manifest(format=m3u8-aapl)

The link above can almost be streamed by IOS AV Player. It turns out the IOS will not stream HTTP. It will only stream HTTPS. Even though the copied URL was HTTP, the same streaming video is also supported via HTTPS so the following URL is the correct form to be consumed by IOS AV Player:

https://devschool01.streaming.mediaservices.windows.net/1adf84ef-530e-422b-aeae-f566bc44ac7d/10SecondSample.ism/manifest(format=m3u8-aapl)