Share via


Add Video to an Audio Session

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.

An audio/video session that you start with just an audio channel can turn into a true audio/video session at any time in the course of a session by adding a video channel to the remote participant’s collection of media channels. The remote participant must be connected to the session at the time you add the video channel and must accept the invitation to add the channel.

To add video to a session, the involved clients execute the following tasks:

  1. Verify the local workstation is set up for video by getting an instance of IUccMediaDeviceManager and calling into GetDevices. You must specify both the type (UCC_MEDIA_TYPES) and direction (UCC_MEDIA_DIRECTIONS) of the media devices to return. The returned collection represents installed devices such as a webcam. For information about configuring media devices, see Configuring Media Devices.
  2. Check the State of the remote participant. The participant must have a state of UCC_SESSION_ENTITY_STATE.UCCSES_CONNECTED.
  3. Create and add a new IUccMediaChannel where the media type is UCC_MEDIA_TYPES.UCCMT_VIDEO. Call into CreateChannel.
  4. Call UpdateChannels on the remote participant.
  5. The remote client handles the OnMediaRequest event and accepts or rejects the invitation to add a video channel.
  6. After the remote participant handles OnMediaRequest and accepts the invitation, the OnUpdateChannels and OnNegotiatedMediaChanged events are raised on the local client. The events can be used to initiate video output on the local client. For information about displaying a video stream, see Displaying Video in an Audio/Video Session.

Adding Video on the Local Client

An instance of the IUccAudioVideoSessionParticipant interface acts as a factory object for the new video channel. You use IUccAudioVideoSessionParticipant to create the channel and add the channel to the media channel collection of the remote participant.

Create and Add a Media Channel

The following example creates and adds a media channel to a remote participant.

        /// <summary>
        /// Adds audio and video media channels to a remote participant
        /// </summary>
        /// <param name="pParticipant">IUccSessionParticipant remote participant to add channel</param>
        /// <param name="pMediaType">UCC_MEDIA_TYPES media type to add</param>
        private void SetParticipantMediaChannel(
            IUccSessionParticipant pParticipant,
            UCC_MEDIA_TYPES pMediaType)
        {
            if (pParticipant == null)
            {
                throw new ArgumentNullException("participant cannot be null");
            }
            if (pMediaType == null)
            {
                throw new ArgumentNullException("Media type cannot be null");
            }
            IUccMediaChannel MediaChannel = null;
            Boolean ChannelExists = false;
            IUccAudioVideoSessionParticipant _AVSessionParticipant = null;

            _AVSessionParticipant = pParticipant as IUccAudioVideoSessionParticipant;
            if (_AVSessionParticipant != null)
            {


                foreach (IUccMediaChannel mChannel in _AVSessionParticipant.Channels)
                {
                    if (mChannel.MediaType == pMediaType)
                    {
                        ChannelExists = true;
                        break;
                    }
                }
                try
                {
                    if (ChannelExists == false)
                    {
                        MediaChannel = _AVSessionParticipant.CreateChannel(pMediaType, null);
                        MediaChannel.PreferredMedia = (int)(UCC_MEDIA_DIRECTIONS.UCCMD_RECEIVE | UCC_MEDIA_DIRECTIONS.UCCMD_SEND);
                        _AVSessionParticipant.AddChannel(MediaChannel);
                    }

                }
                catch (COMException e)
                {
                    MessageBox.Show(
                    "SimpleVideo.VideoControl On Media Channel Added to Participant: COM Exception. Participant: " +
                    pParticipant.Uri.AddressOfRecord + " " + e.Message);
                }

            }//if audio/video participant

        }

Verify State of Remote Participant

The following example verifies that the remote session participant is connected to the active audio/video session.

        /// <summary>
        /// Returns true if remote participant is connected to a session
        /// </summary>
        /// <param name="pParticipant">IUccSessionParticipant remote participant</param>
        /// <returns>Boolean true if remote participant is connected</returns>
        private Boolean IsRemoteParticipantConnected(IUccSessionParticipant pParticipant)
        {
            Boolean returnValue = false;
            if (pParticipant.State == UCC_SESSION_ENTITY_STATE.UCCSES_CONNECTED)
            {
                returnValue = true;
            }
            return returnValue;
        }

Update Remote Participant Media Channels

The following example updates remote participant media channels if the remote participant is connected to a session.

        /// <summary>
        /// Updates a remote participant with a new video channel
        /// </summary>
        /// <param name="pParticipant">IUccSessionParticipant participant to update</param>
        private void UpdateRemoteParticipantChannels(IUccSessionParticipant pParticipant)
        {
            // Verify connected status.
            if (this.IsRemoteParticipantConnected(pParticipant))
            {
                // Create and add video channel.
                this.SetParticipantMediaChannel(pParticipant, UCC_MEDIA_TYPES.UCCMT_VIDEO);

                // Cast IUcSessionParticipant to audio/video session participant interface to expose methods.
                IUccAudioVideoSessionParticipant avParticipant = pParticipant as IUccAudioVideoSessionParticipant;

                // Create new operation context for UpdateChannels operation.
                UccOperationContext opctx = new UccOperationContext();
                UccContext updateChannelContex = new UccContextClass();
                updateChannelContex.AddNamedProperty("videoChannelUpdate", "true");
                opctx.Initialize(1, updateChannelContex);

                // Update the channels.
                avParticipant.UpdateChannels(opctx);

            }
        }

Handle Events

The following example handles the OnNegotiatedMediaChanged method and displays a video stream from the new video channel.

        /// <summary>
        /// Callback function to handle media channel event - negotiated media changed
        /// </summary>
        /// <param name="pEventSource">media channel raising the event</param>
        /// <param name="pEventData">event data</param>
        void _IUccMediaChannelEvents.OnNegotiatedMediaChanged(
            IUccMediaChannel pEventSource,
            UccMediaChannelEvent pEventData)
        {
            if (pEventSource.MediaType == UCC_MEDIA_TYPES.UCCMT_VIDEO)
            {
                this.showVideo(pEventSource);
            }

        }

For a ShowVideo code listing, see Displaying Video in an Audio/Video Session.

Accepting Video Channel on Remote Client

Before accepting an invitation to add a video channel, a client must verify that a video camera is connected to the host computer.

Checking for Media Devices

The following example checks the host computer for a video camera and returns a Boolean true value if it is configured for video.

          /// <summary>
          /// Returns Boolean flag indicating client has enabled video send device
          /// </summary>
          /// <param name="pPlatform">IUccPlatform client platform</param>
          /// <returns>Boolean returnValue</returns>
          public Boolean VideoDeviceCapable(IUccPlatform pPlatform)
          {
              Boolean returnValue = false;
              IUccMediaDeviceManager deviceManager = pPlatform as IUccMediaDeviceManager;

              IUccCollection deviceCollection = deviceManager.GetDevices(
                  UCC_MEDIA_TYPES.UCCMT_VIDEO,
                  UCC_MEDIA_DIRECTIONS.UCCMD_SEND);
              if (deviceCollection.Count > 0)
              {
                  returnValue = true;
              }
              return returnValue;
          }

Handle OnMediaRequest Event

The following example handles the OnMediaRequest by verifying a local host computer has a video camera available, presents the local user with a notification dialog, and then accepts the invitation if the local user indicates agreement.

        /// <summary>
        /// Handles event raised when remote participant has made a request to add
        /// an additional media channel to an audio/video session
        /// </summary>
        /// <param name="pEventSource">IUccAudioVideoSessionParticipant remote participant making the request</param>
        /// <param name="pEventData">UccIncomingMediaRequestEvent event parameter with details of requested media channel</param>
        void _IUccAudioVideoSessionParticipantEvents.OnMediaRequest(
            IUccAudioVideoSessionParticipant pEventSource,
            UccIncomingMediaRequestEvent pEventData)
        {
            StringBuilder sb = new StringBuilder();
            IUccSessionParticipant p = pEventSource as IUccSessionParticipant;

            sb.Append(p.Uri.User + " has added ");
            byte count = 0;
            foreach (IUccMediaChannel mc in pEventData.MediaChannels)
            {
                if (count > 0)
                {
                    sb.Append(" and ");
                }
                sb.Append(mc.MediaType.ToString());
                count++;
            }

            if (this.VideoDeviceCapable(this.Platform) == true)
            {
                sb.Append(Environment.NewLine);
                sb.Append("Do you want to accept the new channels?");
                if (MessageBox.Show(sb.ToString(), "New Channels", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    pEventData.Accept();
                    this.LoadVideoMediachannel(pEventSource);
                }
                else
                {
                    pEventData.Reject(UCC_REJECT_OR_TERMINATE_REASON.UCCROTR_DECLINE);
                }
            }
            else
            {
                pEventData.Reject(UCC_REJECT_OR_TERMINATE_REASON.UCCROTR_NOT_ACCEPTABLE);
            }
        }
        /// <summary>
        /// Display video stream from remote participant
        /// </summary>
        /// <param name="pParticipant">IUccSessionParticipant remote participant</param>
        private void LoadVideoMediachannel(IUccAudioVideoSessionParticipant pParticipant)
        {
            UCC_Advise<_IUccAudioVideoSessionParticipantEvents>(pParticipant, this);

            if (pParticipant.IsLocal != true)
            {
                foreach (IUccMediaChannel c in pParticipant.Channels)
                {
                    if (c.MediaType == UCC_MEDIA_TYPES.UCCMT_VIDEO)
                    {
                        this.showVideo(pParticipant.Channels[(int)UCC_MEDIA_TYPES.UCCMT_VIDEO] as IUccMediaChannel);
                    }
                }

            }
        }

For a ShowVideo code listing, see Displaying Video in an Audio/Video Session.

See Also

Concepts

Conducting an Audio/Video Session
Displaying Video in an Audio/Video Session