In the player templates for Expression Encoder 3 and 4 the “Silverlight Default” and “Smooth Streaming Graphic Player” provide a complex diagnostic graph that provides a lot of detailed information about which bitrate is being played and how well it is being played. This UI is useful for debugging and diagnostic purposes – but has excessive technical detail for general usage. Here a simplified UI is presented that is more suitable for general usage. The simplified UI can be more readily adapted to application specific needs that the more complex graphing UI.
Step 1: Create a custom template. In Encoder select the template you want to base your custom template on and using the command “Edit copy of template in Visual Studio”. – See prior blog post “Making a simple appearance change to an Expression Encoder 4 template using Expression Blend” for a more detailed checklist on how to do this step.
Step 2: Add custom interface required. In Visual Studio find the “PlugInMSSCtrl” project and in that open “PlugInMSSCtrl.cs” in Visual Studio – at the bottom of the file add the following interface definition:
/// <summary>
/// Interface for providing a simplified quality UI
/// </summary>
public interface IPlugInMssSimpleQualityUI
{
/// UIElement to be inserted into the visual tree to display a simple indicator playback quality.
UIElement SimpleQualityUI { get; }
}
Step 3: Prepare the player to use the simplified UI. In the “MediaPlayer” project, edit the file “MediaPlayerAdaptiveSupport.cs” -- near the bottom of the file – find a method named “StartSmoothStreamingPlayback” In this method, find this bit of code:
// Display stats graph if this template has a slot for it.
if (this.m_gridPlugIn != null)
IPlugInMssStatisticsGraph plugInGraph = this.m_mediaElementForSmoothStreamingContent as IPlugInMssStatisticsGraph;
if (plugInGraph != null)
this.m_gridPlugIn.Children.Clear(); // Remove all prior plug ins
this.m_gridPlugIn.Children.Add(plugInGraph.StatisticsGraph);
and replace it with this:
var w = this.m_gridPlugIn.ActualWidth;
if (w > 100)
else
IPlugInMssSimpleQualityUI plugInSimpleUI = this.m_mediaElementForSmoothStreamingContent as IPlugInMssSimpleQualityUI;
if (plugInSimpleUI != null)
this.m_gridPlugIn.Children.Add(plugInSimpleUI.SimpleQualityUI);
Step 4: Add UI place holder for the simple UI – in this example it is added to bottom of the “videoWindow” Grid – but it could be added wherever makes sense for your application. It could also be easily added to the “miscControls” StackPanel.
<Grid x:Name="gridPlugIn" Height="32" Width="35" HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#00FFFFFF" Opacity="1" IsHitTestVisible="False" Margin="3"/>
Step 5: Rebuild the customized player.
Step 6: Begin Adding Simplifed UI to the Smooth Streaming plug-in. In Visual Studio right click on the “PlugInMSSCtrl” project and select “Open Folder In Windows Explorer” -- in Explorer 1st navigate up on level to the “templates” directory – then navigate down into the “SmoothStreamingMediaElement” directory. In that directory, find the “SmoothStreamingMediaElement.SLN” file and open it in Visual Studio. Do a “find in files” search for “IPlugInMssStatisticsGraph” -- there should be four matches – in two of those matches:
replace this line:
public partial class SmoothStreamingMediaElementShim : MediaElementShim, IPlugInMssStatisticsGraph
with this line:
public partial class SmoothStreamingMediaElementShim : MediaElementShim, IPlugInMssStatisticsGraph, IPlugInMssSimpleQualityUI
Step 7: Do a “find in files” search for “UIElement StatisticsGraph” – in the match contained within “SmoothStreamingMediaElementShim,cs” add the following code below the body of the StatisticsGraph property
private UIElement m_plugInSimpleQualityUI;
public UIElement SimpleQualityUI
get
// Initialize plugin UI
if (m_plugInSimpleQualityUI == null)
m_plugInSimpleQualityUI = new SimplfiedQualityUI(this);
return m_plugInSimpleQualityUI;
Step 8: Add actual simplfied UI. In Visual Studio, Right-Click on the “SmoothStreamingMediaElement” project and select “Add->Class” – Select “Silverlight User Control” and then type “SimplfiedQualityUI” as the name. In SimplifiedQualityUI.XAML modify the XAML to this:
<UserControl x:Class="SmoothStreaming.SimplfiedQualityUI"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="32" MinHeight="32">
<TextBlock x:Name="qualityText" Text="" FontSize="10" Foreground="#55FFDDFF" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</UserControl>
Step 9: Add the simplified UI code into SimplifiedQualityUI.XAML.cs
namespace SmoothStreaming
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Expression.Encoder.PlugInMssCtrl;
using Microsoft.Web.Media.SmoothStreaming;
public partial class SimplfiedQualityUI : UserControl
private SimplfiedQualityUI()
InitializeComponent();
/// The actual streaming source object.
private SmoothStreamingMediaElement m_ssme;
/// The shim object to access helper methods
private SmoothStreamingMediaElementShim m_shim;
/// The current playing bitrate.
private ulong m_nowPlayingBitrate;
private uint m_nowPlayingBitrateHeight;
/// Table of bitrates to vertical resolution
private Dictionary<ulong, uint> m_trackHeights;
/// A timer which tracks the stats of the media element
private DispatcherTimer m_timerUIThread;
/// Initializes a new instance of the SmoothStreamingUI class.
/// <param name="source">The smooth streaming source.</param>
internal SimplfiedQualityUI(SmoothStreamingMediaElementShim shim)
if (shim != null)
this.m_shim = shim;
this.m_ssme = shim.ActualMediaElement;
if (this.m_ssme != null)
this.m_ssme.MediaOpened += new RoutedEventHandler(OnMediaElementMediaOpened);
this.m_ssme.PlaybackTrackChanged += new EventHandler<TrackChangedEventArgs>(OnPlayBitrateChange);
/// Callback for the play bitrate changed event.
/// <param name="sender">The object that sent this event</param>
/// <param name="e">Event args for this event</param>
public void OnPlayBitrateChange(object sender, TrackChangedEventArgs e)
if (e.StreamType == MediaStreamType.Video)
this.m_nowPlayingBitrate = e.NewTrack.Bitrate;
uint tmp;
if (this.m_trackHeights.TryGetValue(m_nowPlayingBitrate, out tmp))
this.m_nowPlayingBitrateHeight = tmp;
this.qualityText.Text = GetQualityText(this.m_nowPlayingBitrateHeight);
/// Initialize bitrate graph labels
private void InitBitrates()
this.m_trackHeights = new Dictionary<ulong, uint>();
foreach (var segment in this.m_ssme.ManifestInfo.Segments)
foreach (var stream in segment.AvailableStreams)
if (stream.Type == MediaStreamType.Video)
foreach (var track in stream.AvailableTracks)
uint trackHeight = CPUHeuristic.GetTrackHeight(track);
this.m_trackHeights.Add(track.Bitrate, trackHeight);
private static string GetQualityText(uint height)
string qualityText = string.Empty;
if (height >= 1080)
qualityText = "1080P";
else if (height > 720)
qualityText = "720P+";
else if (height == 720)
qualityText = "720P";
else if (height >= 480)
qualityText = "SD";
qualityText = "LD";
return qualityText;
/// Event handler for the media opened event from the media element.
/// <param name="sender">Source of the event.</param>
/// <param name="e">Event args.</param>
private void OnMediaElementMediaOpened(object sender, RoutedEventArgs e)
InitBitrates();
Step 10: Rebuild the “SmoothStreamingMediaElement” solution. Once it rebuilds correctly – right click on the “SmoothStreamingMediaElement” in the Visual Studio “Solution Explorer” and “Open Folder in Windows Explorer” -- in Explorer find the rebuild “SmoothStreaming.XAP” and copy to the template directory for the customized template – replacing the older version of”SmoothStreaming.XAP” lurking there.
Step 11: Use in Expression Encoder 4
This information is provided "AS IS" with no warrantee and confers no rights.