How to add custom session-based CDN decryption in Silverlight SMFPlayer?

Needless to say, using a DRM product such as PlayReady to protect OTT content is absolutely essential for premium content providers.

One of my MSO customers is so DRM-conscious that they want to do session-based encryption of live smooth streaming content through its CDN on top of (yes, in addition to, not in place of) PlayReady protection. Their argument is that PlayReady 1.5.2 does not yet provide key rotation and they cannot wait for the release of PlayReady 2.0.

As we know, if only PlayReady protection is used, SMFPlayer in Microsoft Media Platform Player Framework (formerly Silverlight Media Framework) handles individualization, license acquiring, decryption and playback.

Now with session-based encryption through CDN on top of PlayReady protection, it is necessary to get session key from CDN and decrypt session-based encryption before turning to PlayReady decryption. While it is straightforward to request session-based decryption key and perform decryption, the question is: how do you integrate this custom decryption logic into your SMFPlayer?

SMFPlayer is highly extensible. We can integrate the custom session-based decryption logic into SMFPlayer through the following steps:

Step 1: Create a custom SMFPlayer class inheriting from SMFPlayer and use this custom SMFPlayer instead of the SMFPlayer;

Step 2: In the custom SMFPlayer, get hold of its SmoothStreamingMediaElement (SSME). Here is the code for doing this:

        //for easy access to SSME

        private SmoothStreamingMediaElement SmoothStreamingMediaElement




                SmoothStreamingMediaElement objSmoothStreamingMediaElement = ActiveMediaPlugin.VisualElement as SmoothStreamingMediaElement;

                return objSmoothStreamingMediaElement;



Step 3: In the custom SMFPlayer, set its SmoothStreamingCache property to a custom SmoothStreamingCache we are going to create in the next step. The code for doing this is shown below:

    //to stop caching, set SmoothStreamingCache to null

    this.SmoothStreamingMediaElement.SmoothStreamingCache = new CustomSmoothStreamingCache();

Step 4: Create the CustomSmoothStreamingCache by inheriting from Microsoft.Web.Media.SmoothStreaming.ISmoothStreamingCache interface.

You can get a sample implementation of smooth streaming cache code from Silverlight IIS Smooth Streaming Offline Cache Sample by Mike Dodaro. However, notice that the sample is for Silverlight Smooth Streaming Client player, not SMFPlayer.

Step 5: You can add your custom decryption logic into the EndPersist method

public bool EndPersist(IAsyncResult ar)



            if (((CacheAsyncResult)ar).Result!= null)


               IsolatedStorageFile isoFileArea = IsolatedStorageFile.GetUserStoreForApplication();

               if (((CacheResponse)(((CacheAsyncResult)ar).Result)).Response.Length < isoFileArea.AvailableFreeSpace)


                   string fileGuid = Guid.NewGuid().ToString();

                  if (!keyUrls.ContainsValue(fileGuid) && !keyUrls.ContainsKey(((CacheAsyncResult)ar).strUrl))   


                        //********* insert custom logic here

                        //CacheResponse objCacheResponse =((CacheResponse)(((CacheAsyncResult)ar).Result));

                        //decrypt objCacheResponse

                        //********* end custom logic


                        IsolatedStorageFileStream isoFile =isoFileArea.CreateFile(fileGuid);




                        keyUrls.Add(((CacheAsyncResult)ar).strUrl, fileGuid);

                        // Save key/value pairs for playback after application restarts.

                        IsolatedStorageSettings.ApplicationSettings.Add(((CacheAsyncResult)ar).strUrl, fileGuid);


                        return true;      


            return false;



Comments (2)

  1. Hello William,

    I have a couple of questions:

    A. Can you confirm that only AFTER EndPersist is called, that the SmoothStreamingMediaElement will put the CacheResponse in the playout buffer [so decrypted]?

    B. You are not showing how one performs the decryption, but am I right to assume that one needs to overwrite the objCacheResponse with the output of the decryptor? In the latter case wouldn't it be easier to perform the decryption in the BeginPersist, as one has to return the response anyhow.

    C. How do you handle the case where the resulting decrypted buffer lenght is smaller then the encrypted one (due to padding) as the objCacheResponse is not "expandable"?



  2. Andrew Hay says:

    Hello William,

    Your code example shows this:

    //decrypt objCacheResponse

    How do you manipulate the stream and return it to the SmoothStreamingMediaElement? It appears this is a one way road. Are you suggesting that it's possible to decrypt the stream and hand it back to the player? I'd love to see how.


    Andrew Hay

Skip to main content