Building Audio/Video Applications based on Player Framework v2.0 for Windows Phone 8, Windows 8.1 and Windows Phone 8.1
INTRODUCTION
This article describes the different steps to create Windows Phone 8, Windows 8.1 and Windows Phone 8.1 applications playing video supporting the following formats:
- Step 1: WMV, MP4, MPEG2-TS (only for Windows 8.1)
- Step 2: WMV, MP4, MPEG2-TS (only for Windows 8.1) and Smooth Streaming
- Step 3: WMV, MP4, MPEG2-TS (only for Windows 8.1), Smooth Streaming and MPEG DASH
- Step 4: WMV, MP4, MPEG2-TS (only for Windows 8.1), Smooth Streaming and MPEG DASH protected with PlayReady
The sample applications delivered with this article allow the user to define:
- the video Uri,
- the PlayReady license acquisition Uri,
- the « Challenge Custom Data » for the PlayReady license acquisition.
If the PlayReady license acquisition Uri is not defined, the application will use the Uri defined in protection header of the manifest.
By default the applications use a list of videos supporting the different formats.
Windows Phone 8 Windows Phone 8.1
STEP 1: AUDIO/VIDEO PLAYER (WMV, MP4, MPEG2-TS)
The Windows Phone 8, Windows 8.1 and Windows Phone 8.1 Applications for Step 1 support the following formats:
- Windows: WMV, MP4, MPEG2-TS
- Windows Phone : WMV, MP4
Those formats are natively supported, no supplementary SDKs are required.
Windows 8.1, Windows Phone 8.1 and Windows Phone 8.0 Applications:
On the XAML MainPage insert the MediaElement and call it « Player »
<MediaElement x:Name="Player" Grid.Row="1" Grid.Column="2" Grid.RowSpan="4" Grid.ColumnSpan="1"
Stretch="Uniform" Margin="20,10,20,10" HorizontalAlignment="Center" VerticalAlignment="Center" />
In the method associated with Click event on button “Play”, initialize Player Source with the Uri of the video you want to play
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with WMV, MP4 and MPEG2-TS format are available on Microsoft Azure
https://livestreamingvm.cloudapp.net/vod/wmv/test1.wmv
https://livestreamingvm.cloudapp.net/vod/mp4/test1.mp4
https://livestreamingvm.cloudapp.net/vod/ts/test1.ts
STEP 2: AUDIO/VIDEO PLAYER (WMV, MP4, MPEG2-TS, SMOOTH STREAMING)
The Windows Phone 8, Windows 8.1 and Windows Phone 8.1 Applications for Step 2 support the following formats:
- Windows: WMV, MP4, MPEG2-TS and Smooth Streaming
- Windows Phone : WMV, MP4 and Smooth Streaming
Supplementary SDKs are required to build the applications :
Windows 8.0 (not required for this application)
Smooth Streaming Client SDK for Windows 8.0:
https://visualstudiogallery.msdn.microsoft.com/04423d13-3b3e-4741-a01c-1ae29e84fea6
Windows 8.1
Smooth Streaming Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/0170c67c-c183-4fee-8dd4-c2b44d710d40
Windows Phone 8.0
Smooth Streaming Client 2.5 SDK for Silverlight and Windows Phone 8 applications:
https://www.microsoft.com/en-us/download/details.aspx?id=42080
Windows Phone 8.1
Smooth Streaming Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/b837ddf3-6884-436e-aeb7-35c6151a8933
Windows 8.1 and Windows Phone 8.1 Applications:
Add a reference to « Microsoft Smooth Streaming Client SDK for Windows 8.1 » for Windows 8.1 application.
Add a reference to « Microsoft Smooth Streaming Client SDK for Windows Phone 8.1 » for Windows Phone 8.1 application.
On the XAML MainPage insert the MediaElement and call it « Player »
<MediaElement x:Name="Player" Grid.Row="1" Grid.Column="2"
Grid.RowSpan="4" Grid.ColumnSpan="1"
Stretch="Uniform" Margin="20,10,20,10"
HorizontalAlignment="Center" VerticalAlignment="Center" />
Create a method RegisterPlugins which associates the Smooth Streaming library with the Smooth Streaming Uri opened by the MediaElement. This method is called in the method OnNavigatedTo.
public Windows.Media.MediaExtensionManager MediaManager;
public IAdaptiveSourceManager AdaptiveSrcManager { get; private set; }
void RegisterPlugins()
{
LogMessage("Register plugins");
if (MediaManager == null)
MediaManager = new Windows.Media.MediaExtensionManager();
if (AdaptiveSrcManager == null)
AdaptiveSrcManager = AdaptiveSourceManager.GetDefault();
PropertySet ssps = new PropertySet();
ssps["{A5CE1DE8-1D00-427B-ACEF-FB9A3C93DE2D}"] = AdaptiveSrcManager;
MediaManager.RegisterByteStreamHandler("Microsoft.Media.AdaptiveStreaming.SmoothByteStreamHandler", ".ism", "text/xml", ssps);
MediaManager.RegisterByteStreamHandler("Microsoft.Media.AdaptiveStreaming.SmoothByteStreamHandler", ".ism", "application/vnd.ms-sstr+xml", ssps);
MediaManager.RegisterByteStreamHandler("Microsoft.Media.AdaptiveStreaming.SmoothByteStreamHandler", ".isml", "text/xml", ssps);
MediaManager.RegisterByteStreamHandler("Microsoft.Media.AdaptiveStreaming.SmoothByteStreamHandler", ".isml", "application/vnd.ms-sstr+xml", ssps);
MediaManager.RegisterSchemeHandler("Microsoft.Media.AdaptiveStreaming.SmoothSchemeHandler", "ms-sstr:", ssps);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LogMessage("OnNavigatedTo");
base.OnNavigatedTo(e);
Application.Current.Suspending += App_Suspending;
Application.Current.Resuming += App_Resuming;
Player.MediaEnded += Player_MediaEnded;
Player.MediaOpened += Player_MediaOpened;
Player.MediaFailed += Player_MediaFailed;
#if WINDOOWS_PHONE_APP
DisplayInformation.GetForCurrentView().OrientationChanged += OnOrientationChanged;
#endif
RegisterPlugins();
}
In the method associated with Click event on button “Play”, initialize Player Source with the Uri of the video you want to play
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with Smooth Streaming format are available on Microsoft Azure
https://livestreamingvm.cloudapp.net/vod/test1/test1.ism/manifest
Applications Windows Phone 8.0:
Add a reference to « Microsoft.Web.Media.SmoothStreaming » for Windows Phone 8.0 application.
On the XAML MainPage :
- insert the MediaElement used to play WMV, MP4 content and call it « Player »
- insert the SmoothStreamingMediaElement used to play Smooth Streaming content and call it « PlayerSSME »
<MediaElement Visibility="Visible" x:Name="Player" Grid.Row="3"
Stretch="Uniform" Grid.Column="0" Grid.ColumnSpan="3" Margin="10,10,10,10"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<ssme:SmoothStreamingMediaElement Visibility="Collapsed"
x:Name="PlayerSSME" Grid.Row="3" Stretch="Uniform" Grid.Column="0"
Grid.ColumnSpan="3" Margin="10,10,10,10" HorizontalAlignment="Center"
VerticalAlignment="Center" />
In the method associated with Click event on button “Play”, initialize PlayerSSME SmoothStreamingSource with the Uri of the smooth streaming video you want to play, if you want to play MP4 or WMV video, initialize Player Source with the Uri of the WMV or MP4 video.
if (MediaUri.Text.EndsWith("/manifest", StringComparison.CurrentCultureIgnoreCase))
PlayerSSME.SmoothStreamingSource = new Uri(MediaUri.Text);
else
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with Smooth Streaming format are available on Microsoft Azure
https://livestreamingvm.cloudapp.net/vod/test1/test1.ism/manifest
STEP 3: AUDIO/VIDEO PLAYER (WMV, MP4, MPEG2-TS, SMOOTH STREAMING, MPEG DASH)
The Windows Phone 8, Windows 8.1 and Windows Phone 8.1 Applications for Step 3 support the following formats:
- Windows: WMV, MP4, MPEG2-TS, Smooth Streaming and MPEG DASH
- Windows Phone : WMV, MP4, Smooth Streaming and MPEG DASH
Supplementary SDKs are required to build the applications :
Windows 8.0 (not required for this application)
Smooth Streaming Client SDK for Windows 8.0:
https://visualstudiogallery.msdn.microsoft.com/04423d13-3b3e-4741-a01c-1ae29e84fea6
Windows 8.1
Smooth Streaming Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/0170c67c-c183-4fee-8dd4-c2b44d710d40
Windows Phone 8.0
Smooth Streaming Client 2.5 SDK for Silverlight and Windows Phone 8 applications:
https://www.microsoft.com/en-us/download/details.aspx?id=42080
Windows Phone 8.1
Smooth Streaming Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/b837ddf3-6884-436e-aeb7-35c6151a8933
Windows Phone 8.0, Windows Phone 8.1 et Windows 8.1
Player Framework for Windows and Windows Phone V2.0:
Windows 8.1 and Windows Phone 8.1 Applications:
Add a reference to:
« Microsoft Smooth Streaming Client SDK for Windows 8.1 »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin» for Windows 8.1 application.
Add a reference to:
« Microsoft Smooth Streaming Client SDK for Windows Phone 8.1 »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin» for Windows Phone 8.1 application.
On the XAML MainPage insert the « PlayerFramework:MediaPlayer » and call it « Player »
<PlayerFramework:MediaPlayer x:Name="Player" Grid.Row="1" Grid.Column="2" Grid.RowSpan="4" Grid.ColumnSpan="1" Margin="20,10,20,10"
IsTimelineVisible="false" IsTimeElapsedVisible="false" IsDurationVisible="false" IsTimeRemainingVisible="false«
IsInfoVisible="false" IsMoreVisible="false« IsFastForwardVisible="False" IsRewindVisible="False"
IsSkipBackVisible="False" IsSkipAheadVisible="False" IsSkipPreviousVisible="False" IsReplayVisible="False"
IsAudioSelectionVisible="False" IsCaptionSelectionVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center"
IsFullScreenVisible="True" Background="Black" />
Create a method RegisterPlugins which associates the Adaptive plugin with the Smooth Streaming Uri opened by the Player. This method is called in the method OnNavigatedTo. Create a method RegisterDashPlugins which associates the DashDownloaderPlugin plugin with the Adaptive plugin used by the Player. This method is called before playing any MPEG DASH content.
public Microsoft.PlayerFramework.Adaptive.AdaptivePlugin adaptivePlugin;
public Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin dashDownloaderPlugin;
void RegisterDashPlugin(bool bRegister)
{
Microsoft.PlayerFramework.Adaptive.AdaptivePlugin plugin = Player.Plugins.OfType<Microsoft.PlayerFramework.Adaptive.AdaptivePlugin>().First();
if (plugin != null)
{
if (bRegister == true)
{
LogMessage("Register DASH plugin");
if (dashDownloaderPlugin == null)
dashDownloaderPlugin = new Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin();
plugin.DownloaderPlugin = dashDownloaderPlugin;
}
else
{
LogMessage("Unregister DASH plugin");
plugin.DownloaderPlugin = null;
}
}
}
void RegisterPlugins()
{
LogMessage("Register plugins");
if (adaptivePlugin == null)
adaptivePlugin = new Microsoft.PlayerFramework.Adaptive.AdaptivePlugin();
Player.Plugins.Add(adaptivePlugin);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LogMessage("OnNavigatedTo");
base.OnNavigatedTo(e);
Application.Current.Suspending += App_Suspending;
Application.Current.Resuming += App_Resuming;
Player.MediaEnded += Player_MediaEnded;
Player.MediaOpened += Player_MediaOpened;
Player.MediaFailed += Player_MediaFailed;
#if WINDOWS_PHONE_APP
DisplayInformation.GetForCurrentView().OrientationChanged += OnOrientationChanged;
#endif
RegisterPlugins();
}
In the method associated with Click event on button “Play”, call the method RegisterDashPlugin to register the DashDownloaderPlugin (if it’s a MPEG DASH uri), and then initialize Player Source with the Uri of the video you want to play.
RegisterDashPlugin((MediaUri.Text.EndsWith(".mpd", StringComparison.CurrentCultureIgnoreCase) ||
MediaUri.Text.EndsWith("manifest(format=mpd-time-csf)", StringComparison.CurrentCultureIgnoreCase)));
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with MPEG DASH format are available on Microsoft Azure.
https://wams.edgesuite.net/media/SintelTrailer_Smooth_SeekDemo/sintel_trailer-1080p.ism/manifest(format=mpd-time-csf)
Applications Windows Phone 8.0:
Add a reference to:
« Microsoft.Web.Media.SmoothStreaming »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin» for the Windows Phone 8.0 application<
On the XAML MainPage insert the « PlayerFramework:MediaPlayer » and call it « Player »
<PlayerFramework:MediaPlayer Visibility="Visible" x:Name="Player" Grid.Row="3" Grid.Column="0"
Grid.ColumnSpan="3" Grid.RowSpan="1" Margin="10,10,10,10" Background="Black" Foreground="Black"
IsAudioSelectionVisible="False" IsCaptionSelectionVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center" IsFullScreenVisible="False" />
Create a method RegisterPlugins which associates the Adaptive plugin with the Smooth Streaming Uri opened by the Player. This method is called in the method OnNavigatedTo. Create a method RegisterDashPlugins which associates the DashDownloaderPlugin plugin with the Adaptive plugin used by the Player. This method is called before playing any MPEG DASH content.
public Microsoft.PlayerFramework.Adaptive.AdaptivePlugin adaptivePlugin;
public Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin dashDownloaderPlugin;
void RegisterDashPlugin(bool bRegister)
{
Microsoft.PlayerFramework.Adaptive.AdaptivePlugin plugin = Player.Plugins.OfType<Microsoft.PlayerFramework.Adaptive.AdaptivePlugin>().First();
if (plugin != null)
{
if (bRegister == true)
{
LogMessage("Register DASH plugin");
if (dashDownloaderPlugin == null)
dashDownloaderPlugin = new Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin();
plugin.DownloaderPlugin = dashDownloaderPlugin;
}
}
}
void RegisterPlugins()
{
LogMessage("Register plugins");
if (adaptivePlugin == null)
adaptivePlugin = new Microsoft.PlayerFramework.Adaptive.AdaptivePlugin();
Player.Plugins.Add(adaptivePlugin);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LogMessage("OnNavigatedTo");
base.OnNavigatedTo(e);
PhoneApplicationService.Current.Deactivated += App_Suspending;
PhoneApplicationService.Current.Activated += App_Resuming;
Player.MediaEnded += Player_MediaEnded;
Player.MediaOpened += Player_MediaOpened;
Player.MediaFailed += Player_MediaFailed;
RegisterPlugins();
}
In the method associated with Click event on button “Play”, first initialize the Player Source with null and close the player. Then call the method RegisterDashPlugin to register the DashDownloaderPlugin (if it’s a MPEG DASH Uri), and then initialize Player Source with the Uri of the video you want to play.
Player.Source = null;
Player.Close();
RegisterDashPlugin((MediaUri.Text.EndsWith(".mpd", StringComparison.CurrentCultureIgnoreCase) ||
MediaUri.Text.EndsWith("manifest(format=mpd-time-csf)", StringComparison.CurrentCultureIgnoreCase)));
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with MPEG DASH format are available on Microsoft Azure.
https://wams.edgesuite.net/media/SintelTrailer_Smooth_SeekDemo/sintel_trailer-1080p.ism/manifest(format=mpd-time-csf)
STEP 4: AUDIO/VIDEO PLAYER (WMV, MP4, MPEG2-TS, SMOOTH STREAMING, MPEG DASH, PLAYREADY)
The Windows Phone 8, Windows 8.1 and Windows Phone 8.1 Applications for Step 4 support the following formats:
- Windows: WMV, MP4, MPEG2-TS, Smooth Streaming and MPEG DASH protected or not with PlayReady DRM
- Windows Phone : WMV, MP4, Smooth Streaming and MPEG DASH protected or not with PlayReady DRM
Supplementary SDKs are required to build the applications :
Windows 8.0 (not required for this application)
Smooth Streaming Client SDK for Windows 8.0:
https://visualstudiogallery.msdn.microsoft.com/04423d13-3b3e-4741-a01c-1ae29e84fea6
Windows 8.1
Smooth Streaming Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/0170c67c-c183-4fee-8dd4-c2b44d710d40
Windows Phone 8.0
Smooth Streaming Client 2.5 SDK for Silverlight and Windows Phone 8 applications:
https://www.microsoft.com/en-us/download/details.aspx?id=42080
Windows Phone 8.1
Smooth Streaming Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/b837ddf3-6884-436e-aeb7-35c6151a8933
Windows Phone 8.0, Windows Phone 8.1 et Windows 8.1
Player Framework for Windows and Windows Phone V2.0:
Windows 8.0 (not required for this application)
PlayReady Client SDK for Windows 8.0:
https://visualstudiogallery.msdn.microsoft.com/e02ccac7-f3eb-4b53-b11a-c657d5631483
Windows 8.1
PlayReady Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/59be4d26-7f00-463e-9d61-2803c36b576b
Windows Phone 8.1
PlayReady Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/477225f7-cb03-4fe6-8c5b-bfc76db7c09f
Steps to acquire a PlayReady license for Universal Apps (Windows 8.1 et Windows Phone 8.1) :
Before describing how the PlayReady client acquires the PlayReady license, some words about the Individualization. Every PlayReady client has a unique digital certificate and key, the installation of the certificate and the key is called Individualization.
Moreover, before the PlayReady client requests the license to decrypt the content, it must first determine whether the user’s computer has the appropriate PlayReady software installed. This software is called the Individualized Black boX (IBX) and is the client component of PlayReady that is required before any protected content can be played. The individualization component software enables the client computer to request and use a PlayReady license.
The PlayReady client for Windows Store applications supports dynamic individualization: the IBX is downloaded from the Individualization Server. In your application you can implement a Pro-Active Individualization Request or a Reactive Individualization Request.
- A Pro-Active Individualization Request can be transmitted just after the installation of the application or when the user launches the application for the first time.
- A Reactive Individualization Request is automatically prepared by the PlayReady client when the application is about to play an asset protected with PlayReady and if the IBX is not installed on the computer.
The schema below describes the acquisition of a PlayReady license to play an asset protected with PlayReady with a Reactive Individualization Request:
The schema below describes the acquisition of a PlayReady license to play an asset protected with PlayReady without any Individualization Request as the Individualized Black Box (IBX) is already installed:
The schema below describes the exchanges between the client and the server when the application plays an asset protected with PlayReady when the Individualized Black Box (IBX) is already installed and the PlayReady license has already been acquired and the license is persistent:
Windows 8.1 and Windows Phone 8.1 applications:
Add a reference to:
« Microsoft Smooth Streaming Client SDK for Windows 8.1 »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin»,
« Microsoft PlayReady Client SDK» for Windows 8.1 application.
Add a reference to:
« Microsoft Smooth Streaming Client SDK for Windows Phone 8.1 »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin»,
« Microsoft PlayReady Client SDK» for Windows Phone 8.1 application.
On the XAML MainPage insert the « PlayerFramework:MediaPlayer » and call it « Player ».
<PlayerFramework:MediaPlayer x:Name="Player" Grid.Row="1" Grid.Column="2" Grid.RowSpan="4" Grid.ColumnSpan="1" Margin="20,10,20,10"
IsTimelineVisible="false" IsTimeElapsedVisible="false" IsDurationVisible="false" IsTimeRemainingVisible="false«
IsInfoVisible="false" IsMoreVisible="false« IsFastForwardVisible="False" IsRewindVisible="False"
IsSkipBackVisible="False" IsSkipAheadVisible="False" IsSkipPreviousVisible="False" IsReplayVisible="False"
IsAudioSelectionVisible="False" IsCaptionSelectionVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center"
IsFullScreenVisible="True" Background="Black" />
Create a method RegisterPlugins which associates the Adaptive plugin with the Smooth Streaming Uri opened by the Player, which creates a MediaProtectionManager associated with the Player and which registers the PlayReady events « ServiceRequested » and « ComponentLoadFailed »
This method is called in the method OnNavigatedTo.
Create a method RegisterDashPlugins which associates the DashDownloaderPlugin plugin with the Adaptive plugin used by the Player. This method is called before playing any MPEG DASH content.
public Microsoft.PlayerFramework.Adaptive.AdaptivePlugin adaptivePlugin;
public Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin dashDownloaderPlugin;
void RegisterDashPlugin(bool bRegister)
{
Microsoft.PlayerFramework.Adaptive.AdaptivePlugin plugin = Player.Plugins.OfType<Microsoft.PlayerFramework.Adaptive.AdaptivePlugin>().First();
if (plugin != null)
{
if (bRegister == true)
{
LogMessage("Register DASH plugin");
if (dashDownloaderPlugin == null)
dashDownloaderPlugin = new Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin();
plugin.DownloaderPlugin = dashDownloaderPlugin;
}
else
{
LogMessage("Unregister DASH plugin");
plugin.DownloaderPlugin = null;
}
}
}
void RegisterPlugins()
{
LogMessage("Register plugins");
if (adaptivePlugin == null)
adaptivePlugin = new Microsoft.PlayerFramework.Adaptive.AdaptivePlugin();
Player.Plugins.Add(adaptivePlugin);
// PlayReady
// Init PlayReady Protection Manager
var protectionManager = new MediaProtectionManager();
Windows.Foundation.Collections.PropertySet cpSystems = new Windows.Foundation.Collections.PropertySet();
cpSystems.Add("{F4637010-03C3-42CD-B932-B48ADF3A6A54}", "Microsoft.Media.PlayReadyClient.PlayReadyWinRTTrustedInput"); //Playready
protectionManager.Properties.Add("Windows.Media.Protection.MediaProtectionSystemIdMapping", cpSystems);
protectionManager.Properties.Add("Windows.Media.Protection.MediaProtectionSystemId", "{F4637010-03C3-42CD-B932-B48ADF3A6A54}");
this.Player.ProtectionManager = protectionManager;
// PlayReady Events registration
Player.ProtectionManager.ComponentLoadFailed += ProtectionManager_ComponentLoadFailed;
Player.ProtectionManager.ServiceRequested += ProtectionManager_ServiceRequested;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LogMessage("OnNavigatedTo");
base.OnNavigatedTo(e);
Application.Current.Suspending += App_Suspending;
Application.Current.Resuming += App_Resuming;
Player.MediaEnded += Player_MediaEnded;
Player.MediaOpened += Player_MediaOpened;
Player.MediaFailed += Player_MediaFailed;
#if WINDOWS_PHONE_APP
DisplayInformation.GetForCurrentView().OrientationChanged += OnOrientationChanged;
#endif
RegisterPlugins();
}
To support PlayReady the application must call the license server to acquire the PlayReady license associated with the content protected with PlayReady. You need to include in the project the file CommonLicenseRequest.cs. This file implements the common class based on HttpClient to acquire the PlayReady license.
The method ProtectionManager_ServiceRequested is called each time the application requests a PlayReady license or an individualization. If it’s a individualization request, the method ReactiveIndivRequest is called. If it’s a license request, the methode LicenseAcquisitionRequest is called.
If the URL used to acquire the PlayReady License is not forced and is the one defined in the PlayReady protection header, the method LicenseAcquisitionRequest calls licenseRequest.BeginServiceRequest. If the URL to acquire the PlayReady License is forced by the application, the method LicenseAcquisitionRequest creates a PlayReady challenge using the ChallengeCustomData and then call licenseAcquisition.AcquireLicense using the URL defined by the user.
private const int MSPR_E_CONTENT_ENABLING_ACTION_REQUIRED = -2147174251;
private string PlayReadyLicenseUrl;
private string PlayReadyChallengeCustomData;
/// <summary>
/// Invoked when the Protection Manager can't load some components
/// </summary>
void ProtectionManager_ComponentLoadFailed(MediaProtectionManager sender, ComponentLoadFailedEventArgs e)
{
LogMessage("ProtectionManager ComponentLoadFailed");
e.Completion.Complete(false);
}
/// <summary>
/// Invoked to acquire the PlayReady License
/// </summary>
async void LicenseAcquisitionRequest(PlayReadyLicenseAcquisitionServiceRequest licenseRequest, MediaProtectionServiceCompletion CompletionNotifier, string Url, string ChallengeCustomData)
{
bool bResult = false;
string ExceptionMessage = string.Empty;
try
{
if (!string.IsNullOrEmpty(Url))
{
LogMessage("ProtectionManager PlayReady Manual License Acquisition Service Request in progress - URL: " + Url);
if (!string.IsNullOrEmpty(ChallengeCustomData))
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] b = encoding.GetBytes(ChallengeCustomData);
licenseRequest.ChallengeCustomData = Convert.ToBase64String(b, 0, b.Length);
}
PlayReadySoapMessage soapMessage = licenseRequest.GenerateManualEnablingChallenge();
byte[] messageBytes = soapMessage.GetMessageBody();
HttpContent httpContent = new ByteArrayContent(messageBytes);
IPropertySet propertySetHeaders = soapMessage.MessageHeaders;
foreach (string strHeaderName in propertySetHeaders.Keys)
{
string strHeaderValue = propertySetHeaders[strHeaderName].ToString();
// The Add method throws an ArgumentException try to set protected headers like "Content-Type"
// so set it via "ContentType" property
if (strHeaderName.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse(strHeaderValue);
else
httpContent.Headers.Add(strHeaderName.ToString(), strHeaderValue);
}
CommonLicenseRequest licenseAcquision = new CommonLicenseRequest();
HttpContent responseHttpContent = await licenseAcquision.AcquireLicense(new Uri(Url), httpContent);
if (responseHttpContent != null)
{
Exception exResult = licenseRequest.ProcessManualEnablingResponse(await responseHttpContent.ReadAsByteArrayAsync());
if (exResult != null)
{
throw exResult;
}
bResult = true;
}
else
ExceptionMessage = licenseAcquision.GetLastErrorMessage();
}
else
{
LogMessage("ProtectionManager PlayReady License Acquisition Service Request in progress - URL: " + licenseRequest.Uri.ToString());
await licenseRequest.BeginServiceRequest();
bResult = true;
}
}
catch (Exception e)
{
ExceptionMessage = e.Message;
}
if (bResult == true)
LogMessage(!string.IsNullOrEmpty(Url) ? "ProtectionManager Manual PlayReady License Acquisition Service Request successful" :
"ProtectionManager PlayReady License Acquisition Service Request successful");
else
LogMessage(!string.IsNullOrEmpty(Url) ? "ProtectionManager Manual PlayReady License Acquisition Service Request failed: " + ExceptionMessage :
"ProtectionManager PlayReady License Acquisition Service Request failed: " + ExceptionMessage);
CompletionNotifier.Complete(bResult);
}
/// <summary>
/// Proactive Individualization Request
/// </summary>
async void ProActiveIndivRequest()
{
PlayReadyIndividualizationServiceRequest indivRequest = new PlayReadyIndividualizationServiceRequest();
LogMessage("ProtectionManager PlayReady ProActive Individualization Service Request in progress...");
bool bResultIndiv = await ReactiveIndivRequest(indivRequest, null);
if (bResultIndiv == true)
LogMessage("ProtectionManager PlayReady ProActive Individualization Service Request successful");
else
LogMessage("ProtectionManager PlayReady ProActive Individualization Service Request failed");
}
/// <summary>
/// Invoked to send the Individualization Request
/// </summary>
async Task<bool> ReactiveIndivRequest(PlayReadyIndividualizationServiceRequest IndivRequest, MediaProtectionServiceCompletion CompletionNotifier)
{
bool bResult = false;
Exception exception = null;
LogMessage("ProtectionManager PlayReady Individualization Service Request in progress...");
try
{
await IndivRequest.BeginServiceRequest();
}
catch (Exception ex)
{
exception = ex;
}
finally
{
if (exception == null)
{
bResult = true;
}
else
{
COMException comException = exception as COMException;
if (comException != null && comException.HResult == MSPR_E_CONTENT_ENABLING_ACTION_REQUIRED)
{
IndivRequest.NextServiceRequest();
}
}
}
if (bResult == true)
LogMessage("ProtectionManager PlayReady Individualization Service Request successful");
else
LogMessage("ProtectionManager PlayReady Individualization Service Request failed");
if (CompletionNotifier != null) CompletionNotifier.Complete(bResult);
return bResult;
}
/// <summary>
/// Invoked to send a PlayReady request (Individualization or License request)
/// </summary>
async void ProtectionManager_ServiceRequested(MediaProtectionManager sender, ServiceRequestedEventArgs srEvent)
{
LogMessage("ProtectionManager ServiceRequested");
if (srEvent.Request is PlayReadyIndividualizationServiceRequest)
{
PlayReadyIndividualizationServiceRequest IndivRequest = srEvent.Request as PlayReadyIndividualizationServiceRequest;
bool bResultIndiv = await ReactiveIndivRequest(IndivRequest, srEvent.Completion);
}
else if (srEvent.Request is PlayReadyLicenseAcquisitionServiceRequest)
{
PlayReadyLicenseAcquisitionServiceRequest licenseRequest = srEvent.Request as PlayReadyLicenseAcquisitionServiceRequest;
LicenseAcquisitionRequest(licenseRequest, srEvent.Completion, PlayReadyLicenseUrl, PlayReadyChallengeCustomData);
}
}
In the method associated with Click event on button “Play”, first initialize PlayReadyLicenseUrl with the Uri of the PlayReady Server (if defined), initialize PlayReadyChallengeCustomData with the data required to generate the PlayReady challenge (if defined). Then call the method RegisterDashPlugin to register the DashDownloaderPlugin (if it’s MPEG DASH Uri), and then initialize Player Source with the Uri of the video you want to play.
PlayReadyLicenseUrl = PlayReadyUri.Text;
PlayReadyChallengeCustomData = CustomData.Text;
RegisterDashPlugin((MediaUri.Text.EndsWith(".mpd", StringComparison.CurrentCultureIgnoreCase) ||
MediaUri.Text.EndsWith("manifest(format=mpd-time-csf)", StringComparison.CurrentCultureIgnoreCase)));
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with MPEG DASH and Smooth Streaming protected with PlayReady format are available with the sample application.
https://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest
https://wams.edgesuite.net/media/SintelTrailer_Smooth_from_WAME_CENC/NoSubSampleAdjustment/sintel_trailer-1080p.ism/manifest(format=mpd-time-csf)
https://wams.edgesuite.net/media/Tears_of_Steel_Smooth_1080p_Protected2/tears_of_steel_1080p.ism/manifest(format=mpd-time-csf)
By default the applications will try to play the following Smooth Streaming asset:
https://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest
using the following URL for the license acquisition:
This URL will return a non-persistent license. Each time the application will try to play the smooth streaming asset, a request to the PlayReady server will be transmitted.
By default, the challenge custom data is empty, you can change this field if the PlayReady server expect a specific challenge custom data.
If you use the following URL, the license returned will be persistent:
https://playready.directtaps.net/pr/svc/rightsmanager.asmx
Applications Windows Phone 8.0:
Add a reference to:
« Microsoft.Web.Media.SmoothStreaming »,
« Microsoft Player Framework »,
« Microsoft Player Framework Adaptive Streaming Plugin»,
« Microsoft Player Framework Dash Plugin» for Windows Phone 8.0 application.
Http Client Library: These PlayReady sample applications are based on Player Framework V2.0 and the PlayReady license acquisition is based on HttpClient class for both platforms Windows and Windows Phone.
HttpClient is a part of .NET Framework 4.5 and Windows Store applications that provides developers an extremely easy way to connect with services across the Internet including REST-based services. HttpClient is available for Windows Phone developers provided you install the Microsoft HttpClient Libraries Nuget package.
On the XAML MainPage insert the « PlayerFramework:MediaPlayer » and call it « Player ».
<PlayerFramework:MediaPlayer Visibility="Visible" x:Name="Player" Grid.Row="3" Grid.Column="0"
Grid.ColumnSpan="3" Grid.RowSpan="1" Margin="10,10,10,10" Background="Black" Foreground="Black"
IsAudioSelectionVisible="False" IsCaptionSelectionVisible="False" HorizontalAlignment="Center" VerticalAlignment="Center" IsFullScreenVisible="False" />
Create a method RegisterPlugins which associates the Adaptive plugin with the Smooth Streaming Uri opened by the Player, which initialize the property “LicenseAcquirer” of Player MediaElement.
This method is called in the method OnNavigatedTo.
Create a method RegisterDashPlugins which associates the DashDownloaderPlugin plugin with the Adaptive plugin used by the Player. This method is called before playing any MPEG DASH content.
public Microsoft.PlayerFramework.Adaptive.AdaptivePlugin adaptivePlugin;
public Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin dashDownloaderPlugin;
void RegisterDashPlugin(bool bRegister)
{
Microsoft.PlayerFramework.Adaptive.AdaptivePlugin plugin = Player.Plugins.OfType<Microsoft.PlayerFramework.Adaptive.AdaptivePlugin>().First();
if (plugin != null)
{
if (bRegister == true)
{
LogMessage("Register DASH plugin");
if (dashDownloaderPlugin == null)
dashDownloaderPlugin = new Microsoft.Media.AdaptiveStreaming.Dash.DashDownloaderPlugin();
plugin.DownloaderPlugin = dashDownloaderPlugin;
}
}
}
void RegisterPlugins()
{
LogMessage("Register plugins");
if (adaptivePlugin == null)
adaptivePlugin = new Microsoft.PlayerFramework.Adaptive.AdaptivePlugin();
Player.Plugins.Add(adaptivePlugin);
// PlayReady
// Init PlayReady
adaptivePlugin.MediaElement.LicenseAcquirer = new WindowsPhoneLicenseAcquisition(null);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
LogMessage("OnNavigatedTo");
base.OnNavigatedTo(e);
PhoneApplicationService.Current.Deactivated += App_Suspending;
PhoneApplicationService.Current.Activated += App_Resuming;
Player.MediaEnded += Player_MediaEnded;
Player.MediaOpened += Player_MediaOpened;
Player.MediaFailed += Player_MediaFailed;
RegisterPlugins();
}
To support PlayReady, the application must call the license server to acquire the PlayReady license associated with the content. You need to include in the project the files CommonLicenseRequest.cs and WindowsPhoneLicenseAcquisition.cs . The file CommonLicenseRequest.cs implements the common class based on HttpClient to acquire the PlayReady license. The file WindowsPhoneLicenseAcquisition.cs implements the class WindowsPhoneLicenseAcquisition derived from the PlayReady class LicenseAcquirer used to acquire the PlayReady license.
In the method associated with the Click event on the « Play » button,
- initialize PlayReadyLicenseUrl with the PlayReady server Uri (if defined),
- initialize PlayReadyChallengeCustomData with the data required to generate the PlayReady challenge (if defined),
- initialize Player Source to null and
- call the Player method « Close » du Player
- if PlayReadyChallengeCustomData is defined, initialize LicenseAcquirer.ChallengeCustomData of Player Media Element.
- if PlayReadyLicenseUrl is defined, initialize LicenseAcquirer.LicenseServerUriOverride of Player Media Element .
- call the method RegisterDashPlugin
- then initialize the Player Source with the content Uri .
PlayReadyLicenseUrl = PlayReadyUri.Text;
PlayReadyChallengeCustomData = CustomData.Text;
// Reset the source and close the player
Player.Source = null;
Player.Close();
Microsoft.PlayerFramework.Adaptive.AdaptivePlugin ap = Player.Plugins.OfType<Microsoft.PlayerFramework.Adaptive.AdaptivePlugin>().FirstOrDefault();
if (ap != null)
{
if (!string.IsNullOrEmpty(PlayReadyChallengeCustomData))
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] b = encoding.GetBytes(PlayReadyChallengeCustomData);
ap.MediaElement.LicenseAcquirer.ChallengeCustomData = Convert.ToBase64String(b, 0, b.Length);
}
if (!string.IsNullOrEmpty(PlayReadyLicenseUrl))
ap.MediaElement.LicenseAcquirer.LicenseServerUriOverride = new Uri(PlayReadyLicenseUrl, UriKind.Absolute);
else
ap.MediaElement.LicenseAcquirer.LicenseServerUriOverride = null;
}
Player.Visibility = System.Windows.Visibility.Visible;
PlayerSSME.Visibility = System.Windows.Visibility.Collapsed;
/// if MPEG DASH Uri Register Dash Plugin
RegisterDashPlugin((MediaUri.Text.EndsWith(".mpd", StringComparison.CurrentCultureIgnoreCase) || MediaUri.Text.EndsWith("manifest(format=mpd-time-csf)", StringComparison.CurrentCultureIgnoreCase)));
Player.Source = new Uri(MediaUri.Text);
Player.Source = null;
Player.Close();
RegisterDashPlugin((MediaUri.Text.EndsWith(".mpd", StringComparison.CurrentCultureIgnoreCase) ||
MediaUri.Text.EndsWith("manifest(format=mpd-time-csf)", StringComparison.CurrentCultureIgnoreCase)));
Player.Source = new Uri(MediaUri.Text);
Sample Uris compliant with MPEG DASH and Smooth Streaming protected with PlayReady format are available with the sample application.
https://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest
https://wams.edgesuite.net/media/SintelTrailer_Smooth_from_WAME_CENC/NoSubSampleAdjustment/sintel_trailer-1080p.ism/manifest(format=mpd-time-csf)
https://wams.edgesuite.net/media/Tears_of_Steel_Smooth_1080p_Protected2/tears_of_steel_1080p.ism/manifest(format=mpd-time-csf)
BUILDING THE APPLICATIONS
In order to build the MediaPlayer sample applications for Windows Phone 8.0, Windows Phone 8.1 and Windows 8.1, make sure you have the basics installed: a computer running Windows 8.1, Visual Studio 2013 Update 2 with Windows Phone 8.1 SDK and the supplementary SDKs:
Smooth Streaming Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/0170c67c-c183-4fee-8dd4-c2b44d710d40
Smooth Streaming Client 2.5 SDK for Silverlight and Windows Phone 8 applications:
https://www.microsoft.com/en-us/download/details.aspx?id=42080
Smooth Streaming Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/b837ddf3-6884-436e-aeb7-35c6151a8933
Player Framework for Windows and Windows Phone V2.0:
PlayReady Client SDK for Windows 8.1:
https://visualstudiogallery.msdn.microsoft.com/59be4d26-7f00-463e-9d61-2803c36b576b
PlayReady Client SDK for Windows Phone 8.1:
https://visualstudiogallery.msdn.microsoft.com/477225f7-cb03-4fe6-8c5b-bfc76db7c09f
DOWNLOADING THE PROJECTS
Download: C# (15.7 MB)
Requires: Windows Phone 8, Windows 8.1, Windows Phone 8.1, Visual Studio 2013 Update 2
Last updated: 5/28/2014
License: MS-LPL
Technologies: PlayReady, WMV, MP4, MPEG2-TS, Smooth Streaming, MPEG DASH,
Player Framework, C#, XAML
Topics: PlayReady Smooth Streaming MPEG DASH Player for Windows Phone and Windows Store
Comments
Anonymous
August 12, 2014
I try to use this tutorial to create app to play iptv. But only plays hd stream, stream with mpeg-2 - failed. There are some solution to play mpeg-2Anonymous
August 15, 2014
I tried your example step 3 with Windows 8.1/VS 2013 Update 2/Player Framework v2.0 to play MPEG-DASH content. it threw a first-chance exception at Microsoft.Media.AdaptiveStreaming.dll) in the executable with access violation reading location 0x0000000000000000. Any clue on what might be the issue here? Thanks.Anonymous
April 13, 2015
please how to use the LogMessage method and from the codes above there were some methods that were not created but were used...