Randomizing a Playlist
Previous | Next |
Randomizing a Playlist
You can randomize a playlist to change the user experience each time a client connects. The following example illustrates how to randomly order the media elements in a playlist. The Shuffle subroutine is called recursively so that all nested child elements of a media element are also randomly ordered.
Visual Basic .NET Example
Imports Microsoft.WindowsMediaServices.Interop Imports interop_msxml Private Sub RandomizePlylst() ' Declare variables. Dim Playlist As IXMLDOMDocument Dim Root_Node As IXMLDOMNode Dim Server As WMSServer Try ' Create the WMSServer object. Server = New WMSServer() ' Load an existing playlist. Playlist = Server.CreatePlaylist Playlist.load("c:\wmpub\wmroot\Playlist.wsx") ' Find the root node. The root node is the smil element. Root_Node = Playlist.documentElement ' Call the Shuffle() subroutine. Call Shuffle(Root_Node) ' Save the modified playlist. Playlist.save("c:\wmpub\wmroot\ModifiedPlaylist.wsx") Catch Err As Exception ' TODO: Exception handler goes here. Finally ' TODO: Clean-up code goes here. End Try End Sub Private Sub Shuffle(ByVal ParentNode As IXMLDOMNode) ' Declare variables. Dim bHasChildren As Boolean Dim ChildList As IXMLDOMNodeList Dim lNumChildren As Long Dim lNumChildrenInArray As Long Dim lIndex As Long Dim ChildNode As IXMLDOMNode Dim NextRandomChildNode As IXMLDOMNode Dim OldChild As IXMLDOMNode Dim RandomList() As IXMLDOMNode Try ' Determine whether the parent node has children. If so, ' the children must be shuffled. Exit the subroutine if ' the parent has no children. bHasChildren = ParentNode.hasChildNodes If Not bHasChildren Then Exit Sub ' Retrieve the child nodes. ChildList = ParentNode.childNodes lNumChildren = ChildList.length If lNumChildren = 0 Then Exit Sub ' Dimension the RandomList() array. ReDim RandomList(lNumChildren - 1) ' Remove all of the children so that you can ' insert them back later in a different order. For lIndex = 0 To lNumChildren - 1 ' When you remove a child, the number of children ' is decremented by one. Therefore, you must ' delete the first child. ChildNode = ChildList.item(0) OldChild = ParentNode.removeChild(ChildNode) ' Recursively randomize all children of the child ' element. Call Shuffle(ChildNode) ' Store the children in an array. RandomList(lIndex) = ChildNode ChildNode = Nothing Next ' Initialize the random number generator. Randomize() ' Randomly insert each child into the playlist. lNumChildrenInArray = lNumChildren Do While lNumChildrenInArray > 0 ' Randomly pick a child to insert. lIndex = Int((lNumChildrenInArray - 1) * Rnd()) NextRandomChildNode = RandomList(lIndex) ' Append the child to the parent node. OldChild = Nothing OldChild = ParentNode.appendChild(NextRandomChildNode) ' Compact the child node list. If lIndex = lNumChildrenInArray - 1 Then RandomList(lIndex) = Nothing Else RandomList(lIndex) = Nothing RandomList(lIndex) = RandomList(lNumChildrenInArray - 1) RandomList(lNumChildrenInArray - 1) = Nothing End If ' Decrement the loop counter. lNumChildrenInArray = lNumChildrenInArray - 1 Loop Catch Err As Exception ' TODO: Exception handler goes here. Finally ' TODO: Clean-up code goes here. End Try End Sub
C# Example
using Microsoft.WindowsMediaServices.Interop; using interop_msxml; private void Randomize() { // Declare variables. IXMLDOMDocument Playlist; IXMLDOMNode Root_Node; WMSServer Server; try { // Create the WMSServer object. Server = new WMSServerClass(); // Load an existing playlist. Playlist = Server.CreatePlaylist(); Playlist.load("c:\\wmpub\\wmroot\\Playlist.wsx"); // Find the root node. The root node is the smil element. Root_Node = Playlist.documentElement; // Call the Shuffle() subroutine. Shuffle(Root_Node); // Save the modified playlist. Playlist.save("c:\\wmpub\\wmroot\\ModifiedPlaylist.wsx"); } catch (Exception) { // TODO: Exception handler goes here. } finally { // TODO: Clean-up code goes here. } } private void Shuffle(IXMLDOMNode ParentNode) { // Declare variables. bool bHasChildren; long lNumChildren; long lNumChildrenInArray; long lIndex; Random r = new Random(); IXMLDOMNodeList ChildList; IXMLDOMNode ChildNode; IXMLDOMNode NextRandomChildNode; IXMLDOMNode OldChild; IXMLDOMNode[] RandomList; try { // Determine whether the parent node has children. If so, // the children must be shuffled. Exit the subroutine if // the parent has no children. bHasChildren = ParentNode.hasChildNodes(); if (!bHasChildren) return; // Retrieve the child nodes. ChildList = ParentNode.childNodes; lNumChildren = ChildList.length; if (lNumChildren == 0) return; // Dimension the RandomList() array. RandomList = new IXMLDOMNode[lNumChildren]; // Remove all of the children so that you can // insert them back later in a different order. for (lIndex=0; lIndex<lNumChildren; lIndex++) { // When you remove a child, the number of children // is decremented by one. Therefore, you must // delete the first child. ChildNode = ChildList[0]; OldChild = ParentNode.removeChild(ChildNode); // Recursively randomize all children of the child // element. Shuffle(ChildNode); // Store the children in an array. RandomList[lIndex] = ChildNode; ChildNode = null; } // Randomly insert each child into the playlist. lNumChildrenInArray = lNumChildren; while (lNumChildrenInArray > 0) { // Randomly pick a child to insert. lIndex = r.Next(0, (int)(lNumChildrenInArray - 1)); NextRandomChildNode = RandomList[lIndex]; // Append the child to the parent node. OldChild = null; OldChild = ParentNode.appendChild(NextRandomChildNode); // Compact the child node list. if (lIndex == lNumChildrenInArray - 1) { RandomList[lIndex] = null; } else { RandomList[lIndex] = null; RandomList[lIndex] = RandomList[lNumChildrenInArray - 1]; RandomList[lNumChildrenInArray - 1] = null; } // Decrement the loop counter. lNumChildrenInArray = lNumChildrenInArray - 1; } } catch (Exception) { // TODO: Exception handler goes here. } finally { // TODO: Clean-up code } }
C++ Example
// Include header files. #include <windows.h> #include "wmsserver.h" #include <atlbase.h> // Includes CComBSTR and CComVariant. #include <time.h> // Declare functions. void Randomize(); void Shuffle(IXMLDOMNode *pParentNode); void Randomize() { // Declare variables. IXMLDOMDocument *pPlaylist; IXMLDOMNode *pRoot_Node; IWMSServer *pServer; CComVariant varFile, varPath; VARIANT_BOOL bVal; HRESULT hr; // Initialize the COM library and retrieve a pointer // to an IWMSServer interface. hr = CoInitialize(NULL); if (FAILED(hr)) goto EXIT; hr = CoCreateInstance(CLSID_WMSServer, NULL, CLSCTX_ALL, IID_IWMSServer, (void **)&pServer); if (FAILED(hr)) goto EXIT; // Create a playlist object. hr = pServer->CreatePlaylist(&pPlaylist); if (FAILED(hr)) goto EXIT; // Load an existing playlist. varFile = "c:\\wmpub\\wmroot\\playlist.wsx"; hr = pPlaylist->load(varFile, &bVal); if (FAILED(hr)) goto EXIT; // Find the root node. The root node of a server-side // playlist must be the smil element. hr = pPlaylist->get_documentElement((IXMLDOMElement**)&pRoot_Node); if (FAILED(hr)) goto EXIT; // Call the Shuffle() subroutine. Shuffle(pRoot_Node); // Save the playlist. varPath = "c:\\wmpub\\wmroot\\modifiedplaylist.wsx"; hr = pPlaylist->save(varPath); if (FAILED(hr)) goto EXIT; EXIT: // TODO: Release temporary COM objects and uninitialize COM. return; } void Shuffle(IXMLDOMNode *pParentNode) { // Declare variables. IXMLDOMNodeList *pChildList; IXMLDOMNode *pChildNode, *pNextRandomChildNode, *pOldChild, *pRandomList[256]; VARIANT_BOOL bHasChildren; long lNumChildren, lNumChildrenInArray, lIndex, iFound[256]; HRESULT hr; double r,x; bool bFound = true; int i; // Initialize the array of "found" random integers to -1. for (i=0; i<256; i++) { iFound[i] = -1; } // Determine whether the parent node has children. If so, // the children must be shuffled. Exit the subroutine if // the parent has no children. hr = pParentNode->hasChildNodes(&bHasChildren); if (FAILED(hr)) goto EXIT; if (!bHasChildren) return; // Retrieve the child nodes. hr = pParentNode->get_childNodes(&pChildList); hr = pChildList->get_length(&lNumChildren); if (FAILED(hr)) goto EXIT; if (lNumChildren == 0) return; // Remove all of the children so that you can // insert them back later in a different order. for (lIndex=0; lIndex<lNumChildren; lIndex++) { // When you remove a child, the number of children // is decremented by one. Therefore, you must // delete the first child. hr = pChildList->get_item(0, &pChildNode); hr = pParentNode->removeChild(pChildNode, &pOldChild); if (FAILED(hr)) goto EXIT; // Recursively randomize all children of the child // element. Shuffle(pChildNode); // Store the children in an array. pRandomList[lIndex] = pChildNode; pChildNode = NULL; } // Randomly insert each child into the playlist. srand((unsigned)time(NULL)); lNumChildrenInArray = lNumChildren; while (lNumChildrenInArray > 0) { // Randomly pick a child to insert. do { r = ((double)rand() / (double)(RAND_MAX+1)); x = (r * (lNumChildren)); lIndex = (long)x; // Search for the index value. for (i=0; i<256; i++) { if (lIndex == iFound[i]) { bFound = true; break; } } if (i == 256) bFound = false; } while (bFound == true); // Reset bFound for the next iteration bFound = true; // Place the new index in the iFound array. This array // identifies all of the random values used. for (i=0; i<256; i++) { if (iFound[i] == -1) { iFound[i] = lIndex; break; } } pNextRandomChildNode = pRandomList[lIndex]; // Append the child to the parent node. pOldChild = NULL; pParentNode->appendChild(pNextRandomChildNode, &pOldChild); // Decrement the loop counter. lNumChildrenInArray = lNumChildrenInArray - 1; } EXIT: // TODO: Release temporary COM objects and uninitialize COM. return; }
See Also (General)
See Also (Visual Basic .NET)
- IWMSServer Object (Visual Basic .NET)
- IXMLDOMDocument Object (Visual Basic .NET)
- IXMLDOMElement Object (Visual Basic .NET)
- IXMLDOMNodeList Object (Visual Basic .NET)
See Also (C#)
- IWMSServer Object (C#)
- IXMLDOMDocument Object (C#)
- IXMLDOMElement Object (C#)
- IXMLDOMNodeList Object (C#)
See Also (C++)
Previous | Next |