Partager via


Using the FireEvent Method

You can use the FireEvent method on the IWMSPlaylist interface to change the position of the server in a playlist. For example, if you programmatically add a media element to a position in the playlist that the server has already passed, you can navigate back to that element by using the FireEvent method in conjunction with the begin attribute. You can also use the FireEvent method to insert an emergency notice into a presentation. Both concepts are illustrated by the following example.

Assume that a client has requested the following playlist and is receiving the Windows Media file Movie.wmv. The playlist contains a priorityClass element for which the peers attribute is set to "pause".

<?wsx version="1.0"?>
<smil>
  <excl>
    <priorityClass peers="pause">
      <media src="c:\wmpub\wmroot\Movie.wmv" begin="0h" />
    </priorityClass>
  </excl>
</smil>

To insert an emergency announcement into the playlist, you must first create a new media element, identify the source of the announcement, and specify that the element begins when the appropriate event notice is sent.

It is recommended that you use the IWMSPlaylist::CueStream method to cue the new media element before you try to stream it. The CueStream method is asynchronous, but it does not have an associated callback method. It is therefore recommended that you wait for a few seconds and use the IWMSPlaylist::IsStreamCued property to determine whether the media element is ready.

Note

It is recommended that you do not use the FireEvent method on an on-demand publishing point when fast caching is enabled. Fast caching downloads the content to the client at a rate faster than real time, and after the content is downloaded, the client reconnects to the server only to perform a freshness check. Because of the accelerated speed of the download and subsequent freshness checks, your ability to fire an event to the playlist at the proper moment is extremely limited.

The following examples illustrate how to insert a new media element into an existing playlist programmatically. The new element begins playing when the EmergencyNotice event is sent by using the FireEvent method.

Visual Basic .NET Example

Imports Microsoft.WindowsMediaServices.Interop
Imports interop_msxml

Private Sub EventFire()

  ' Declare variables.
  Dim Server As WMSServer
  Dim Player As IWMSPlayer
  Dim Playlist As IWMSPlaylist
  Dim ElementMedia As IXMLDOMElement
  Dim Priority_Element As IXMLDOMElement
  Dim Priority_Child As IXMLDOMElement
  Dim NewElement As IXMLDOMElement
  Dim I As Integer

  Try
    ' Create the WMSServer object.
    Server = New WMSServer()

    ' Retrieve the requested playlist for the first connected player.
    Player = Server.Players.Item(0)
    Playlist = Player.RequestedPlaylist

    ' Create a media element for the playlist.
    ElementMedia = Playlist.createElement("media")

    ' Set the begin attribute for the media element.
    ElementMedia.setAttribute("begin", "EmergencyNotice")

    ' Set the src attribute for the media element.
    ElementMedia.setAttribute("src", " c:\wmpub\wmroot\Notice.wmv")

    ' Find the second child of the root node. In this example,
    ' the second child is the priorityClass element.
    Priority_Element = Playlist.documentElement.firstChild.firstChild

    ' Retrieve the first media element in the priorityClass element.
    Priority_Child = Priority_Element.firstChild

    ' Insert the new node.
    NewElement = Priority_Element.insertBefore(ElementMedia, Priority_Child)

    ' Cue the new media element.
    Playlist.CueStream(ElementMedia)

    ' Send an event after the media element is cued.
    ' Because CueStream() is asynchronous, it is recommended
    ' that you suspend the thread for a few seconds.
    For I = 1 To 10
      System.Threading.Thread.Sleep(1000)
      If Playlist.IsStreamCued(ElementMedia) Then
        Playlist.FireEvent("EmergencyNotice")
        Exit For
      End If
    Next

  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;

// Declare variables.
WMSServer      server;
IWMSPlayer     player;
IWMSPlaylist   playlist;
IXMLDOMElement element_media, priority_element, priority_child, new_element;
int            i;
    
try
{
  // Create a new WMSServer object.
  server = new WMSServer();

  // Retrieve the requested playlist for the first connected player.
  player = server.Players[0];
  playlist = player.RequestedPlaylist;
    
  // Create a media element for the playlist.
  element_media = playlist.createElement("media");
    
  // Set the begin attribute for the media element.
  element_media.setAttribute("begin", "EmergencyNotice");
    
  // Set the src attribute for the media element.
  element_media.setAttribute("src", " c:\\wmpub\\wmroot\\notice.wmv");
    
  // Find the second child of the root node. In this example,
  // the second child is the priorityClass element.
  priority_element = (IXMLDOMElement)playlist.documentElement.firstChild.firstChild;
  priority_child = (IXMLDOMElement)priority_element.firstChild;
    
  // Retrieve the first media element in the priorityClass element.
  new_element = (IXMLDOMElement)priority_element.insertBefore(element_media, priority_child);
    
  // Cue the new media element.
  playlist.CueStream(element_media);
    
  // Send an event after the media element is cued. Because 
  // CueStream() is asynchronous, it is recommended that you 
  // suspend the thread for several seconds.
  for (i=0; i<10; i++)
  {
    System.Threading.Thread.Sleep(1000);
    if (playlist.get_IsStreamCued(element_media))
    {
      playlist.FireEvent("EmergencyNotice");
      break;
    }
  }
}

catch(Exception)
{
  // TODO: Exception handler goes here.
}

finally
{
  // TODO: Clean-up code goes here.
}

C++ Example

// Include header files.
#include <windows.h>
#include "wmsserver.h"
#include <atlbase.h>    // Includes CComBSTR and CComVariant.

// Declare variables and interfaces.
IWMSServer      *pServer;
IWMSPlayers     *pPlayers;
IWMSPlayer      *pPlayer;
IWMSPlaylist    *pPlaylist;
IXMLDOMElement  *pElement_Media;
IXMLDOMElement  *pTemp_Element;
IXMLDOMNode     *pPriority_Child;
IXMLDOMNode     *pFirstChild;
IXMLDOMNode     *pSecondChild;
CComBSTR        bstrAttrName, bstrElementName, bstrEventname;
CComVariant     varAttr, varIndex;
VARIANT_BOOL    bVal;
HRESULT         hr;
int             i;

// 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;

// Retrieve a pointer to the player collection.
hr = pServer->get_Players(&pPlayers);
if (FAILED(hr)) goto EXIT;
    
// Retrieve a pointer to the first player in the collection.
varIndex = 0;
hr = pPlayers->get_Item(varIndex, &pPlayer);
if (FAILED(hr)) goto EXIT;

// Retrieve a pointer to the requested playlist for the first player.
hr = pPlayer->get_RequestedPlaylist(&pPlaylist);
if (FAILED(hr)) goto EXIT;

// Create a media element for the playlist.
bstrElementName = "media";
hr = pPlaylist->createElement(bstrElementName, &pElement_Media);
if (FAILED(hr)) goto EXIT;

// Set the begin attribute for the media element.
bstrAttrName = "begin";
varAttr = "EmergencyNotice";
hr = pElement_Media->setAttribute(bstrAttrName, varAttr);
if (FAILED(hr)) goto EXIT;

// Set the src attribute for the media element.
bstrAttrName = "src";
varAttr = "c:\\wmpub\\wmroot\\notice.wmv";
hr = pElement_Media->setAttribute(bstrAttrName, varAttr);
if (FAILED(hr)) goto EXIT;

// Find the second child of the root node. In this example,
// the second child is the priorityClass element. Insert
// the new media element at this location.
hr = pPlaylist->get_documentElement(&pTemp_Element);
if (FAILED(hr)) goto EXIT;

hr = pTemp_Element->get_firstChild(&pFirstChild);
if (FAILED(hr)) goto EXIT;

hr = pFirstChild->get_firstChild(&pSecondChild);
if (FAILED(hr)) goto EXIT;

hr = pSecondChild->insertBefore((IXMLDOMNode *)pElement_Media, 
                                  (CComVariant)NULL, &pPriority_Child);
if (FAILED(hr)) goto EXIT;

// Cue the new media element.
hr = pPlaylist->CueStream(pElement_Media);
if (FAILED(hr)) goto EXIT;

// Send an event after the media event is cued. Because 
// CueStream() is asynchronous, it is recommended that you
// suspend the thread for several seconds. This is done with the
// Sleep() function found in the Win32 API.
for (i=0; i<10; i++)
{
  Sleep(1000);
  hr = pPlaylist->get_IsStreamCued(pElement_Media, &bVal);
  if (FAILED(hr)) goto EXIT;

  if (VARIANT_TRUE == bVal)
  {
    bstrEventname = "EmergencyNotice";
    hr = pPlaylist->FireEvent(bstrEventname);
    if (FAILED(hr)) goto EXIT;
    break;
  }
}

EXIT:
  // TODO: Release temporary COM objects and uninitialize COM.

The preceding example code creates the following playlist object.

<smil>
  <excl>
    <priorityClass peers="pause">
      <media src="c:\wmpub\wmroot\Notice.wmv" begin="EmergencyNotice" />
      <media src="c:\wmpub\wmroot\Movie.wmv" begin="0h" />
    </priorityClass>
  </excl>
</smil>

See Also (General)

See Also (Visual Basic .NET)

See Also (C#)

See Also (C++)