Continuing with our exploration of new and shiny stuff in Windows 8.1 Apps SDK, today we explore the Media Player and see how we can build a UPnP/DLNA Media Client with it.
With exploding number of wirelessly connected devices, media sharing via any means is now a hot thing. However instead of slinging media from one device to another, if you had a network-connected storage in your home itself, that could stream media hosted on it, it would be awesome. Well universal plug and play and DLNA are media sharing protocols that do exactly the same. Windows 8 supports Media Sharing inherently. In fact you can setup a Media Server with a $35 Raspberry Pi and a big USB Storage device plugged into it.
Given this availability of media, a Windows 8 Store client that could play media from any such media devices on the network, would be truly awesome. Why wait, let’s build one rightaway using XAML and C#.
Building the Windows 8.1 Media Client
We start off with a Blank App Template project.
The XAML Layout
We update the default Grid to contain three columns and two rows. We add the following controls on to the XAML Canvas:
1. AppTitle TextBlock: Placed in Row(0) Col(1), this is the application title with its text set to ‘PiMedia Player’. If you have read my Raspberry Pi adventures you’ll know why I am calling it so.
2. MediaTitle TextBlock: Placed in Row(0) Col(2), this is more of a status message text letting us know the status of the action. When the Media is being played, it shows the name of the Media file.
3. AvailableMediaDevices ComboBox: Placed in Row(1), Col(1), this contains the list of Media Devices on the Network. It is loaded once the App is started.
4. Back Button: Placed in Row(1), Col(1) below the AvailableMediaDevices ComboBox, this button is for going back one folder while navigating Media
5. MediaList ListBox: Place in Row(1), Col(1) below the Home button, this lists either the Folders or the files in them.
6. Player MediaElement: This is the new Media Element that’s a part of Windows 8.1 API capable of playing various media types. Its worth noting the XAML for the Player is as simple as this
<MediaElement x:Name="Player" Grid.Column="2" Margin="10,10,0,10" Grid.Row="1" AreTransportControlsEnabled="True"/>
The final UI at Design Time looks like this

The Implementation
Again for sake of simplicity, we have not used an MVVM framework, instead we’ve used Code Behind to wire up the functionality.
1. To start off with we have the following properties to manage local data
IReadOnlyList<StorageFolder> MediaServers { get; set; }
IReadOnlyList<StorageFolder> MediaFolders { get; set; }
IReadOnlyList<StorageFile> MediaFiles { get; set; }
StorageFile CurrentMediaFile { get; set; }
Stack<StorageFolder> PreviousFolders { get; set; }
MediaServers: The list of Media Services available to the machine
MediaFolders: The current set of Folders shown in the MediaList
MediaFiles: The current set of Files shown in the MediaList
CurrentMediaFile: If the App is playing a media file the handle to that file.
PreviousFolders: A stack to maintain the folders as we step through them This is used by the Back button when navigating back through the device folders.
2. In the Constructor we initialize the PreviousFolders stack and then call the InitializeMediaServers method.
public MainPage()
{
this.InitializeComponent();
PreviousFolders = new Stack<StorageFolder>();
this.InitilizeMediaServers();
}
3. The InitializeMediaServers method clears out the AvailableMediaDevices dropdown and gets the Media Server Devices available. WinRT makes it a single line API call to fetch Media Servers which is truly awesome. If one or more servers are found, we loop through them and add their titles to the AvailableMediaDevices ComboBox. The complete code listing is as follows:
async private void InitilizeMediaServers()
{
try
{
AvailableMediaDevices.Items.Clear();
MediaServers = await KnownFolders.MediaServerDevices.GetFoldersAsync();
if (MediaServers.Count == 0)
{
MediaTitle.Text = "No MediaServers found";
}
else
{
foreach (StorageFolder server in MediaServers)
{
AvailableMediaDevices.Items.Add(server.DisplayName);
}
MediaTitle.Text = "Media Servers refreshed";
}
}
catch (Exception ex)
{
MediaTitle.Text = "Error querying Media Servers :" + ex.Message;
}
}
4. Next we handle the SelectionChanged event of the AvailableMediaDevices ComboBox. The event handler simply stop the player (if it was playing media already), clears the MediaList and calls the LoadMediaFiles method, passing it the Selected MediaServer.
private void AvailableMediaDevices_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Player.Stop();
MediaList.Items.Clear();
if (AvailableMediaDevices.SelectedIndex != -1)
{
MediaTitle.Text = "Retrieving media files ...";
LoadMediaFiles(MediaServers[AvailableMediaDevices.SelectedIndex]);
}
}
5. LoadMediaFiles method loads all the subfolders and media files into the MediaList ListBox. The Folders are loaded first and prepended with a “ + “ for easily distinguishing them from Files.
Once all the folders have been loaded, we check if the current folder has the name “All Video”. If it does, we apply a query to limit the results to Video files and the results count to 25 only. This is just for the demo to show the various API options you could get all the files for all folder types if desired.
So this method populates the MediaFolders and MediaFiles lists.
async private void LoadMediaFiles(StorageFolder mediaServerFolder)
{
try
{
MediaFolders = await mediaServerFolder.GetFoldersAsync();
MediaList.Items.Clear();
if (MediaFolders.Count > 0)
{
MediaList.Items.Clear();
foreach (StorageFolder folder in MediaFolders)
{
MediaList.Items.Add(" + " + folder.DisplayName);
}
MediaTitle.Text = "Media folders retrieved";
}
var queryOptions = new QueryOptions();
var queryFolder = mediaServerFolder.CreateFileQueryWithOptions(queryOptions);
MediaFiles = await queryFolder.GetFilesAsync();
if (MediaFiles.Count > 0)
{
foreach (StorageFile file in MediaFiles)
{
MediaList.Items.Add(file.DisplayName);
}
MediaTitle.Text = "Media files retrieved";
}
}
catch (Exception ex)
{
MediaTitle.Text = "Error locating media files " + ex.Message;
}
}
6. Next we implement the SelectionChanged event of the MediaList control. On change of the Selected Index, we stop the Player from playing its current video (if any). Thereafter we use the SelectedIndex to calculate if the selection is for a Folder or a File. If it is a Folder, the LoadMediaFiles is called; if it’s a file, it’s set as the current file and assigned to the Player.
private async void MediaList_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
try
{
Player.Stop();
if (MediaList.SelectedIndex != -1 && MediaList.SelectedIndex <
MediaFolders.Count && MediaFolders.Count != 0)
{
MediaTitle.Text = "Retrieving media files ...";
LoadMediaFiles(MediaFolders[MediaList.SelectedIndex]);
}
else if (MediaList.SelectedIndex != -1 && (MediaList.SelectedIndex >=
MediaFolders.Count &&
MediaList.SelectedIndex < (MediaFolders.Count + MediaFiles.Count)))
{
CurrentMediaFile = MediaFiles[MediaList.SelectedIndex - MediaFolders.Count];
var stream = await CurrentMediaFile.OpenAsync(FileAccessMode.Read);
Player.SetSource(stream, CurrentMediaFile.ContentType);
Player.Play();
MediaTitle.Text = "Playing: " + CurrentMediaFile.DisplayName;
}
}
catch (Exception ex)
{
MediaTitle.Text = "Error during file selection :" + ecp.Message;
}
}
7. Finally we have the Click handler of the Back Button. Here we check we are at the Top of the stack or not. If not, we pop the topmost element and re load the files of the new Top folder of the stack.
private void Back_Click(object sender, RoutedEventArgs e)
{
if (PreviousFolders.Count > 1)
{
PreviousFolders.Pop();
LoadMediaFiles(PreviousFolders.Peek());
}
}
Believe it or not we are actually all done. It’s a total of 160 odd lines of code!
Actually there is one last thing that we need to do before we can take it out for a spin! Update the Package Manifest to declare Private Networks, Music Library, Videos Library and Internet (Client & Server) capabilities.

Once you had updated the manifest as above, time to take it for a Spin.
Network Media Player Demo
On first run, we are presented with the following screen

I select a Media Service and get the following

I navigate a few folders deep to my Training folder to get a list of Folders and one File in the root folder
I navigate into the “2013-TechEdNA” folder and select the first File

We can see the video starts playing. We can Pause it, seek to a different position, Go FullScreen or Zoom In if we want to in the player itself. Pretty neat for the minimal code we wrote.
Conclusion
We saw how to build a Media Player that plays videos off UPnP shares created by any OS including Windows 7 and Windows 8. The MediaElement control is a rather capable control with a nice set of base functionalities built in.
Download the entire source code of this article (Github)
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @
sumitkm or email him at sumitkm [at] gmail