This documentation is archived and is not being maintained.

Recorder

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

A Recorder is an entity that is capable of receiving audio media that comes from an AudioVideoFlow instance and recording it to a file. Depending on the state of the attached AudioVideoFlow instance, a Recorder can automatically start or stop.

Unlike the Player class, which has two modes of operation, the Recorder class can be thought of as having only one mode of operation, which is similar to Automatic mode in the Player class. If an application calls the Start method on a Recorder instance, nothing will be recorded until an active AudioVideoFlow instance is attached to it. In addition, if there is no active AudioVideoFlow instance attached to a Recorder instance, or if the AudioVideoFlow instance is detached or terminated, the Recorder instance stops automatically.

If a Recorder instance has begun recording a file, an application can cause recording to stop by calling the Stop method, and state changes in the attached AudioVideoFlow instance can also cause the Recorder instance to stop. For example, if the State property on the AudioVideoFlow instance changes from Active to Terminated, the Recorder instance stops. Non-state configuration changes in the AudioVideoFlow instance, such as Hold, Retrieve, Mute, and changing the media channel direction, do not stop the Recorder instance. For example, if a call being recorded remains on hold for five minutes, the Recorder instance records five minutes of silence.

A Recorder will not record to a file with the hidden attribute. This can cause problems that are difficult to rectify, because no error message is reported in an attempt to record to a hidden file.

Caution noteCaution

Files recorded by a Recorder device do not support Digital Rights Management (DRM). This means that conversations recorded by a Recorder device can be played by any player that supports the Windows Media Audio (WMA) media format, potentially exposing personal or confidential information.

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

Caution noteCaution

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 Recorder instance appear 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 Recorder instance, using the constructor for this class.

  2. Attach the flow to the recorder, using the AttachFlow method on the Recorder class.

  3. Create the object that receives the recording, using the WmaFileSink constructor. The parameter to this constructor is a string that contains the name of the WMA file that will be created. As previously mentioned, the file should not be a hidden file.

  4. Register for the StateChanged event.

  5. Call the recorder’s SetSink method, which informs the recorder of where the recorded data should go.

  6. Start the recorder, using the Start method on the Recorder instance.

  7. Stop the recorder, using the Stop method on the Recorder instance.

  8. Detach the flow from the Recorder instance, using the DetachFlow method.

public void Run()
{

  // Initialize and start up 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/received.
  _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 to go Active.
  autoResetAVFlowActiveEvent.WaitOne();

  // Set up a recorder to record the audio from the remote side.
  // 1) Create a recorder.
  Recorder recorder = new Recorder();
  // 2) Attach the flow to the recorder.
  recorder.AttachFlow(_audioVideoFlow);

  // 3) Register for StateChanged event.
  recorder.StateChanged += new EventHandler<RecorderStateChangedEventArgs>(recorder_StateChanged);

  // 4) Create a WmaFileSink in which to record. 
  WmaFileSink sink = new WmaFileSink("recording.wma");
  // 5) Inform the recorder about the recording destination.
  recorder.SetSink(sink);

  // 6) Start the recorder.
  recorder.Start();

  Thread.Sleep(9000);

  // 7) Stop the recorder.
  recorder.Stop();

  // 8) Detach the flow from the recorder.
  recorder.DetachFlow();

  collabPlatform.BeginShutdown(EndPlatformShutdown, _collabPlatform);

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

The Recorder class has the following constructor.

// Creates a new instance of the Recorder class.
public Recorder();

The following are the public properties on the Recorder class.

// Gets the Recorder state.
public RecorderState State {get;}

// Gets the destinatation to be recorded to, by the Recorder.
public MediaSink Sink {get;}

// Gets the attached AudioVideoFlow.
public AudioVideoFlow AudioVideoFlow {get;}


The following are the public methods on the Recorder class.

// Starts recording media from a session.
// Can be used to initiate a new recording or to resume a paused recording.
public void Start();

// Stops recording.
public void Stop();

// Pauses recording. To resume recording, call Start.
public void Pause();

// Sets the mode of the Recorder.
public void SetMode(RecorderMode mode);

// Sets the sink for this Recorder.
public void SetSink(MediaSink sink);

// Removes this Recorder’s sink.
public void RemoveSink();

// Attaches an AudioVideoFlow.
public void AttachFlow(AudioVideoFlow audioVideoFlow);

// Detaches an AudioVideoFlow.
// If there is no AudioVideoFlow attached to the Recorder, this method simply returns.
public void DetachFlow();


Start throws InvalidOperationException if MediaSink is null, and throws OperationFailureException for several reasons, including I/O errors.

SetSink throws ArgumentNullException if sink is null, and throws InvalidOperationException if the Recorder is already started.

AttachFlow throws ArgumentNullException if its AudioVideoFlow argument is null, and throws InvalidOperationException if its argument is already attached to any Recorder.

The following are the public events on the Recorder class.

// Raised to notify an application that Recorder state has changed.
public event EventHandler<RecorderStateChangedEventArgs> StateChanged;
Show: