The AudioVideoFlowclass has no public constructors, but instead relies on settings in an AudioVideoFlowTemplateinstance to initialize or modify an AudioVideoFlowinstance.
After an AudioVideoFlowTemplateinstance has been created, its settings can be copied to an AudioVideoFlowinstance by a call to the Initializemethod on the AudioVideoFlowclass. This initialization must occur within the body of a handler for the AudioVideoFlowConfigurationRequestedevent. Alternatively, an AudioVideoFlowTemplateinstance can be set and then passed in a call to the BeginApplyChangesmethod on the AudioVideoFlowclass.
AudioVideoFlowTemplateand AudioVideoFlowinstances are independent of one another. A new AudioVideoFlowTemplateinstance can be created each time an AudioVideoFlowinstance is to be set or modified, or a single AudioVideoFlowTemplateinstance can be used to set or modify multiple AudioVideoFlowinstances.
Initializing an AudioVideoFlow Instance
The technique of calling Initializeto initialize an AudioVideoFlowinstance can be used only when the AudioVideoFlowis in the Idlestate, and only within the body of a handler for the AudioVideoFlowConfigurationRequestedevent.
Copy Code | |
---|---|
AudioVideoFlow _audioVideoFlow; ... public void audioVideoCall_FlowConfigurationRequested(object sender, AudioVideoFlowConfigurationRequestedEventArgs e) { _audioVideoFlow = e.Flow; // Register an event handler for the StateChanged event. // When the flow becomes Active, as indicated by the StateChanged event, the program will perform media-related actions. _audioVideoFlow.StateChanged += new EventHandler<MediaFlowStateChangedEventArgs>(audioVideoFlow_StateChanged); // Change the default behavior before the negotiation is completed. // Create a template based on the current AudioVideoFlow. AudioVideoFlowTemplate template = new AudioVideoFlowTemplate(_audioVideoFlow); // Accept only 8Khz audio sampling rate codecs. template.Audio.Channels[ChannelLabel.AudioMono].SamplingRate = AudioSamplingRate.EightKhz; // Change _audioVideoFlow settings according to the template. _audioVideoFlow.Initialize(template); } // Very simple handler for the StateChanged event. void audioVideoCall_StateChanged(object sender, CallStateChangedEventArgs e) { Console.WriteLine("Call has changed state. The previous call state was: " + e.PreviousState + " and the current state is: " + e.State); } |
Important: |
---|
The AudioVideoFlowTemplateconstructor throws InvalidOperationExceptionif the state of its AudioVideoFlowparameter is in the Terminatedstate. |
Modifying an AudioVideoFlowTemplate Instance
The settings of an AudioVideoFlowinstance can also be changed by a call to BeginApplyChanges.
In the following code example, which is shown only for purposes of illustration, it is assumed that AVCall, an AudioVideoCallinstance, previously has been created, and that the state of _audioVideoFlowis Active.
Copy Code | |
---|---|
AudioVideoFlow _audioVideoFlow; ... AudioVideoFlowTemplate AVFTemplate = new AudioVideoFlowTemplate(AVCall.Flow); AVFTemplate.EncryptionPolicy = MediaEncryption.Supported; AVFTemplate.Audio.GetChannels()[ChannelLabel.AudioMono].AllowedDirection = MediaChannelDirection.SendOnly; _audioVideoFlow.BeginApplyChanges(AVFTemplate, ApplyChangesCallback, null); ... void ApplyChangesCallback(IAsyncResult asyncResult) { try { _audioVideoFlow.EndApplyChanges(asyncResult); } catch { // handle exceptions } } |
Negotiation Between Local and Remote Endpoints
After an AudioVideoFlowinstance has been initialized or modified, negotiation with the remote participant is carried out. Settings such as HoldStatusand AllowedDirectionon the remote endpoint can affect the resulting AudioVideoFlowsettings. For example, if the application sets AllowedDirectionto MediaChannelDirection. SendReceive, but the remote has previously set AllowedDirectionto MediaChannelDirection. SendOnly, the Directionsetting on the local endpoint will become MediaChannelDirection. ReceiveOnly.
The following steps show the values of AllowedDirection, Direction, and HoldStatusafter negotiations have finished.
- The local endpoint sets
AllowedDirectionto
MediaChannelDirection.
SendReceive, and
HoldStatusis
HoldType.
None. On the remote endpoint,
AllowedDirection=
MediaChannelDirection.
SendOnly.
Result: Directionon the local endpoint will be set to MediaChannelDirection. ReceiveOnly. - The local endpoint applies a hold to both ends, using a call to
BeginHold(
HoldType.
BothEndpoints, , ).
Results: AllowedDirectionis MediaChannelDirection. SendReceive, HoldStatusis set to HoldType. BothEndpoints, and Directionon the local endpoint will be set to MediaChannelDirection. Inactive. - The local endpoint removes the hold, using a call to
BeginRetrieve.
Results: AllowedDirectionis MediaChannelDirection. SendReceive, HoldStatusis set to HoldType. None, and Directionon the local endpoint will depend on the response from the remote endpoint. If the remote endpoint responds with MediaChannelDirection. SendReceive, then Directionwill be set to MediaChannelDirection. SendReceive. If the remote endpoint responds with MediaChannelDirection. SendOnly(as in step 1), then Directionon the local endpoint will be set to MediaChannelDirection. ReceiveOnly.
In negotiation with a remote endpoint, if the local endpoint sends an offer that places a restriction on the media flow by a change in the direction or by placing a hold, it does not matter if the remote endpoint rejects the offer. On the other hand, if the local endpoint sends an offer that removes existing restrictions, it waits for the remote endpoint to accept or reject the offer.
Operations that mute a media flow do not require negotiation.