The Playerclass represents an entity that is capable of playing media to one or more media flows, and as such, provides a simple, scalable way to play an audio segment in a Windows Media Audio (WMA) file to multiple listeners. A Playerinstance renders the media that is represented by an instance of a subclass of the MediaSourceabstract base class. The output from a Playerinstance goes to one or more AudioVideoFlowinstances.

A Playeracts as a pointer to a MediaSourceobject, and determines the current position to play in the media.

The Playerclass has two modes of operation:

The simplest arrangement is a single Playerinstance with a single attached AudioVideoFlowinstance, as shown in the following illustration.



Single player, single AudioVideoFlow instance

Another arrangement is to have a single Playerinstance that has multiple AudioVideoFlowinstances, as shown in the following illustration. In this arrangement, the audio media to be played has a single play position and all attached AudioVideoFlowinstances receive exactly the same audio simultaneously. This capability is useful for providing Music on Hold, or for broadcasting audio to multiple listeners.



Single Player, multiple AudioVideoFlow instances

A third arrangement is to have multiple Playerinstances with multiple attached AudioVideoFlowinstances, as shown in the following illustration. Each Playerinstance determines a different playing point in the media source. The AudioVideoFlow instances attached to a given Player instance (for example, AudioVideoFlow 1 and AudioVideoFlow 2 that are attached to Player 1) receive the same audio at the same time, but AudioVideoFlow instances attached to different Player instances receive different audio segments at any given time (for example, AudioVideoFlow 1 and AudioVideoFlow 3 that are attached, respectively, to Player 1 and Player 2). This capablity is useful for providing Welcome messages to listeners when they arrive at a conference.



Multiple Player instances, multiple AudioVideoFlow instances

The Playerclass is scalable. Together with a MediaSourceobject, it will decide the best way to store data. For example, if MediaSourceis a file, raw data will be read only if new channel encoding (for example, SIREN or RTAudio) is needed. In buffered mode, the MediaSourcecaches encoded versions of media. A MediaSourcecan be opened in buffered mode ( MediaSourceOpenMode.Buffered) or in unbuffered mode ( MediaSourceOpenMode.Unbuffered). When an encoded stream is reused, playing the cached stream provides significant performance gains.

The following code example shows the steps involved in using a Player.

Caution:
This code example is not a complete example. Several methods, properties, and events are used in this example, but are not defined within the example.

The essential points of creating and using a Playerinstance are shown in the following steps. Each step is assocated with a line of code that is preceded by a comment with a number in it.

  1. Create a Playerinstance, using the constructor for this class.

  2. Attach the flow to the player, using the AttachFlowmethod on the Playerclass.

  3. Register for the player’s StateChangedevent.

  4. Load the file that is to be played into memory by creating a WmaFileSourceinstance. The string parameter is the name of the WMA file to be played.

  5. Prepare the source file, using the BeginPrepareSourcemethod on the WmaFileSourceinstance. The caller can specify whether the file is to be opened in Bufferedmode or in Unbufferedmode. In the example code, the argument to EndPrepareSourceis the return value from BeginPrepareSource.

  6. Set the player’s mode, using the SetModemethod. In the example, the mode is set to Automatic, which means that the player will begin playing only when the Stateof the attached AutoVideoFlowinstance is Active. The Player stops when it reaches the end of the file or when there are no attached AudioVideoFlowinstances that are Active. If the mode were set to Manual, the player would start playing immediately.

  7. Inform the player about the source of the media it will play, using the SetSourcemethod.

  8. Start the player, using the player’s Startmethod.

  9. Pause the player, using the player’s Pausemethod. This step is shown only to demonstrate how to pause the player.

  10. Restart the player after it was paused, using the Startmethod.

  11. Stop the player, using the player’s Stopmethod.

  12. Close the source, using the Closemethod on the WmaFileSourceinstance. An application must close the source when it is not longer needed. A source that is not closed can result in a memory leak.

  13. Detach the flow, using the player’s DetachFlowmethod.

Copy Code
public void Run()
{
  // Initialize and startup the platform.
  ClientPlatformSettings clientPlatformSettings = new
ClientPlatformSettings(_applicationName,
Microsoft.Rtc.Signaling.SipTransportType.Tls);
  _collabPlatform = new
CollaborationPlatform(clientPlatformSettings);
  _collabPlatform.BeginStartUp(EndPlatformStartup,
_collabPlatform);

  // Sync; wait for the startup to complete.
  _autoResetEvent.WaitOne();


  // Initialize and register the endpoint, using the credentials of
the user the application will be acting as.
  UserEndpointSettings userEndpointSettings = new
UserEndpointSettings(_userURI, _userServer);
  userEndpointSettings.Credential = _credential;
  _userEndpoint = new UserEndpoint(_collabPlatform,
userEndpointSettings);
  _userEndpoint.BeginEstablish(EndEndpointEstablish,
_userEndpoint);

  // Sync; wait for the registration to complete.
  _autoResetEvent.WaitOne();


  // Set up the conversation and place the call.
  ConversationSettings convSettings = new ConversationSettings();
  convSettings.Priority = _conversationPriority;
  convSettings.Subject = _conversationSubject;
  // Conversation represents a collection of modalities in the
context of a dialog with one or multiple callees.
  Conversation conversation = new Conversation(_userEndpoint,
_calledParty, convSettings);

  _audioVideoCall = new AudioVideoCall(conversation);

  // Call: StateChanged: Only hooked up for logging.
  _audioVideoCall.StateChanged += new
EventHandler<CallStateChangedEventArgs>(audioVideoCall_StateChanged);

  // Subscribe to the AudioVideoFlowConfigurationRequested event;
the flow will be used to send the media.
  // Ultimately, as a part of the callback, the media will be
sent/recieved.
  _audioVideoCall.AudioVideoFlowConfigurationRequested += new
EventHandler<AudioVideoFlowConfigurationRequestedEventArgs>(audioVideoCall_FlowConfigurationRequested);



  // Place the call to the remote party;
  _audioVideoCall.BeginEstablish(EndCallEstablish,
_audioVideoCall);

  // Sync; wait for the call to complete.
  _autoResetEvent.WaitOne();

  // Sync; wait for the AudioVideoFlow goes Active
  _autoResetAVFlowActiveEvent.WaitOne();

  // 1) Create a Player and attach to AVFlow
  Player player = new Player();
  // 2) Attach the Player to the AVFlow
  player.AttachFlow(_audioVideoFlow);

  // 3) Subscribe to player StateChanged event, including the play
completed event. 
  player.StateChanged += new
EventHandler<PlayerStateChangedEventArgs>(player_StateChanged);

  // 4) Load the file into memory
	WmaFileSource source = new WmaFileSource("startup.wma");
  
  // 5) Prepare the source for the player.
 
source.EndPrepareSource(source.BeginPrepareSource(MediaSourceOpenMode.Buffered,
null, null));

  // 6) Set the play mode. In automatic mode, player will start
playing only when the flow is in the active state.
  // In manual mode, player will start playing immediately.
  player.SetMode(PlayerMode.Automatic);

  // 7) Inform the player about the source.
  player.SetSource(source);

  // 8) Start the player.
	player.Start();

	Thread.Sleep(2000);

  // 9) Pause the player.
	player.Pause();

	Thread.Sleep(2000);

  // 10) Restart the player.
  player.Start();

	Thread.Sleep(5000);

  // 11) Stop the player.
  player.Stop();

  // 12) Source must be closed after it is no longer needed,
otherwise memory will not be released even after garbage
collection.
  source.Close();

  // 13) Player must be detached from the flow, otherwise if the
player is rooted, it will keep the flow in memory.
  player.DetachFlow(_audioVideoFlow);


  _collabPlatform.BeginShutdown(EndPlatformShutdown,
_collabPlatform);

  // Wait for shutdown to occur.
  _autoResetShutdownEvent.WaitOne();
} 

Player Constructors

The Playerclass has the following constructors.

Copy Code
// Creates a new instance of the Player class with State set to
Stopped.
public Player();

Player Properties

The following are the public properties on the Playerclass.

Copy Code
// Gets the media to be played by the Player.
public MediaSource Source {get;}

// Gets the state of the Player.
public PlayerState State {get;}

// Gets the AudioVideoFlows attached to the player.
public ReadOnlyCollection<AudioVideoFlow> AudioVideoFlows
{get;}

// Gets the current mode of the Player.
public PlayerMode Mode {get;}

Player Methods

The following are the public methods on the Playerclass.

Copy Code
// Sets the mode of the Player, which can be either Automatic or
Manual.
public void SetMode(PlayerMode mode);

// Sets the MediaSource for the Player.
public void SetSource(MediaSource source);

// Removes the sink from this Player.
public void RemoveSource();

// Attaches an AudioVideoFlow.
// If there is already an AudioVideoFlow instance attached, the
method merely returns.
public void AttachFlow(AudioVideoFlow audioVideoFlow);

// Detaches an AudioVideoFlow.
// If the Player is not already attached to a flow, the method
merely returns.
public void DetachFlow(AudioVideoFlow audioVideoFlow);

// Plays the attached MediaSource.
public void Start();

// Stops playing the MediaSource and
// resets the current playing position to the beginning of the
media.
public void Stop();

// Pauses playing MediaSource, keeping the current playing
position.
// Throws InvalidOperationException if MediaSource is not attached
or there are no sessions bound.
public void Pause();

// Allows the current play position to be moved. Method can be
called in any state. 
// The argument value can be positive (to move forward) or negative
(to move backward.
public void Skip(int milliSeconds);

SetSourcethrows InvalidOperationExceptionif Stateon the Playeris not Stopped.

AttachFlowthrows ArgumentNullExceptionif the AudioVideoFlowargument is null.

DetachFlowthrows ArgumentNullExceptionif the AudioVideoFlowargument is null.

Startthrows InvalidOperationExceptionif Sourceis null, unprepared, or closed, or if the Playeris already in the Startedstate, and throws OperationFailureExceptionfor several reasons, including an overloaded system.

Pausethrows InvalidOperationExceptionif the Playeris not in the Startedstate.

Player Events

The following are the public events on the Playerclass.

Copy Code
// Raised to notify an application that the Player state changed.
public event EventHandler<PlayerStateChangedEventArgs>
StateChanged;