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:
-
Automatic(the default)
In Automaticmode, the behavior of a Playerinstance depends on the state of the attached AudioVideoFlowinstance. If an application calls the Startmethod on the Playerinstance, the Stateproperty on the Playerinstance changes to Started, but nothing is played until there is an active AudioVideoFlowinstance attached to the Playerinstance (that is, until the Stateproperty on the AudioVideoFlowinstance is Active).
If the last active AudioVideoFlowinstance is detached or terminated while a Playerinstance in Automaticmode is playing, the Playerinstance stops automatically. -
Manual
In Manualmode, a Playerinstance can operate with or without an attached AudioVideoFlowinstance, although no one would be able to listen to the file being played if there were no attached AudioVideoFlowinstance. If the last active AudioVideoFlowinstance is detached or terminated while a Playerinstance in Manualmode is playing, the Playerinstance continues playing. In this regard, a Playerinstance in Manualmode behaves like a CD player whose speakers are disconnected.
The simplest arrangement is a single Playerinstance with a single attached AudioVideoFlowinstance, as shown in the following illustration.
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.
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.
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.
- Create a
Playerinstance, using the constructor for this class.
- Attach the flow to the player, using the
AttachFlowmethod on the
Playerclass.
- Register for the player’s
StateChangedevent.
- 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.
- 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.
- 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.
- Inform the player about the source of the media it will play,
using the
SetSourcemethod.
- Start the player, using the player’s
Startmethod.
- Pause the player, using the player’s
Pausemethod. This step is shown only to demonstrate how to
pause the player.
- Restart the player after it was paused, using the
Startmethod.
- Stop the player, using the player’s
Stopmethod.
- 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.
- 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; |