public MeetingResult Subscribe(int accountId, int resourceId, MediaType mediaType)
        {
            MeetingResult result = new MeetingResult();

            Participant participant = null;

            switch (mediaType)
            {
            case MediaType.Camera:

                var cameraParam = StreamParameterProviders.GetParameter <SubscribeCameraStreamParameter>(string.Empty);
                if (_participants.TryGetValue(accountId, out participant))
                {
                    StreamResource <IStreamParameter> streamResource =
                        participant.Resources.SingleOrDefault(res => res.ResourceId == resourceId);

                    if (streamResource == null)
                    {
                        throw new NullReferenceException("流缓存不存在。");
                    }

                    SubscribeVideoModel subscribeCameraModel = cameraParam.GetSubscribeVideoModel();
                    //subscribeCameraModel.AvSyncGroupId = (uint)streamResource.SyncId;
                    subscribeCameraModel.ResourceId = resourceId;
                    subscribeCameraModel.UserId     = accountId.ToString();

                    VideoBox videoBox;
                    if (VideoBoxManager.TryGet(participant.Account, VideoBoxType.None, mediaType, out videoBox))
                    {
                        subscribeCameraModel.VideoRecvModel.DisplayWindow = videoBox.Handle;
                        videoBox.AccountResource.ResourceId = resourceId;
                        videoBox.AccountResource.MediaType  = mediaType;
                    }

                    MeetingResult subscribeCameraResult = _meetingSdkWrapper.SubscribeVideo(subscribeCameraModel);

                    if (subscribeCameraResult.StatusCode == 0)
                    {
                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        streamResource.IsUsed = true;
                        if (videoBox != null)
                        {
                            //await _meetingSdkWrapper.StartRemoteVideoRender(accountId, resourceId, videoBox.Handle,
                            //    (int)videoBox.Host.ActualWidth,
                            //    (int)videoBox.Host.ActualHeight);
                        }
                    }

                    result = subscribeCameraResult;
                }

                break;

            case MediaType.Microphone:

                var micParam = StreamParameterProviders.GetParameter <SubscribeMicStreamParameter>(string.Empty);
                if (_participants.TryGetValue(accountId, out participant))
                {
                    var streamResource =
                        participant.Resources.SingleOrDefault(res => res.ResourceId == resourceId);

                    if (streamResource == null)
                    {
                        throw new NullReferenceException("流缓存不存在。");
                    }

                    SubscribeAudioModel subscribeMicModel = micParam.GetSubscribeAudioModel();

                    subscribeMicModel.UserId = accountId.ToString();
                    //subscribeMicModel.AvSyncGroupId = (uint)streamResource.SyncId;
                    subscribeMicModel.ResourceId = resourceId;
                    string audioOutputDeviceName;
                    if (!_deviceNameAccessor.TryGetSingleName(DeviceName.Speaker, out audioOutputDeviceName))
                    {
                        throw new Exception("扬声器未设置!");
                    }
                    subscribeMicModel.AudioRecvModel.SourceName = audioOutputDeviceName;

                    var subscribeMicResult = _meetingSdkWrapper.SubscribeAudio(subscribeMicModel);
                    if (subscribeMicResult.StatusCode == 0)
                    {
                        streamResource.IsUsed = true;
                    }

                    result = subscribeMicResult;
                }


                break;

            case MediaType.VideoDoc:

                var winCapParam = StreamParameterProviders.GetParameter <SubscribeDataCardStreamParameter>(string.Empty);
                if (_participants.TryGetValue(accountId, out participant))
                {
                    var streamResource =
                        participant.Resources.SingleOrDefault(res => res.ResourceId == resourceId);

                    if (streamResource == null)
                    {
                        throw new NullReferenceException("流缓存不存在。");
                    }

                    SubscribeVideoModel subscribeWinCapModel = winCapParam.GetSubscribeVideoModel();
                    //subscribeWinCapModel.AvSyncGroupId = (uint)streamResource.SyncId;
                    subscribeWinCapModel.ResourceId = resourceId;
                    subscribeWinCapModel.UserId     = accountId.ToString();

                    VideoBox videoBox;
                    var      user = Participants.FirstOrDefault(p => p.Account.AccountId == accountId);

                    if (VideoBoxManager.TryGet(user.Account, VideoBoxType.DataCard, mediaType, out videoBox))
                    {
                        subscribeWinCapModel.VideoRecvModel.DisplayWindow = videoBox.Handle;
                        videoBox.AccountResource.ResourceId = resourceId;
                        videoBox.AccountResource.MediaType  = mediaType;
                    }

                    MeetingResult subscribeWinCapResult = _meetingSdkWrapper.SubscribeVideo(subscribeWinCapModel);

                    if (subscribeWinCapResult.StatusCode == 0)
                    {
                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        streamResource.IsUsed = true;
                        if (videoBox != null)
                        {
                            //await _meetingSdkWrapper.StartRemoteVideoRender(accountId, resourceId, videoBox.Handle,
                            //    (int)videoBox.Host.ActualWidth,
                            //    (int)videoBox.Host.ActualHeight);
                        }
                    }

                    result = subscribeWinCapResult;
                }


                break;

            case MediaType.AudioDoc:
            case MediaType.AudioCaptureCard:

                var docMicParam = StreamParameterProviders.GetParameter <SubscribeMicStreamParameter>(string.Empty);
                if (_participants.TryGetValue(accountId, out participant))
                {
                    var streamResource =
                        participant.Resources.SingleOrDefault(res => res.ResourceId == resourceId);

                    if (streamResource == null)
                    {
                        throw new NullReferenceException("流缓存不存在。");
                    }

                    SubscribeAudioModel subscribeMicModel = docMicParam.GetSubscribeAudioModel();

                    subscribeMicModel.UserId = accountId.ToString();
                    //subscribeMicModel.AvSyncGroupId = (uint)streamResource.SyncId;
                    subscribeMicModel.ResourceId = resourceId;
                    string audioOutputDeviceName;
                    if (!_deviceNameAccessor.TryGetSingleName(DeviceName.Speaker, out audioOutputDeviceName))
                    {
                        throw new Exception("扬声器未设置!");
                    }
                    subscribeMicModel.AudioRecvModel.SourceName = audioOutputDeviceName;

                    var subscribeMicResult = _meetingSdkWrapper.SubscribeAudio(subscribeMicModel);
                    if (subscribeMicResult.StatusCode == 0)
                    {
                        streamResource.IsUsed = true;
                    }

                    result = subscribeMicResult;
                }

                break;

            case MediaType.VideoCaptureCard:

                var dataCardParam = StreamParameterProviders.GetParameter <SubscribeWinCaptureStreamParameter>(string.Empty);
                if (_participants.TryGetValue(accountId, out participant))
                {
                    var streamResource =
                        participant.Resources.SingleOrDefault(res => res.ResourceId == resourceId);

                    if (streamResource == null)
                    {
                        throw new NullReferenceException("流缓存不存在。");
                    }

                    SubscribeVideoModel subscribeDataCardModel = dataCardParam.GetSubscribeVideoModel();
                    //subscribeDataCardModel.AvSyncGroupId = (uint)streamResource.SyncId;
                    subscribeDataCardModel.ResourceId = resourceId;
                    subscribeDataCardModel.UserId     = accountId.ToString();

                    VideoBox    videoBox;
                    Participant user = Participants.FirstOrDefault(p => p.Account.AccountId == accountId);

                    if (VideoBoxManager.TryGet(user.Account, VideoBoxType.WinCapture, mediaType, out videoBox))
                    {
                        subscribeDataCardModel.VideoRecvModel.DisplayWindow = videoBox.Handle;
                        videoBox.AccountResource.ResourceId = resourceId;
                        videoBox.AccountResource.MediaType  = mediaType;
                    }

                    MeetingResult subscribeCameraResult =
                        _meetingSdkWrapper.SubscribeVideo(subscribeDataCardModel);

                    if (subscribeCameraResult.StatusCode == 0)
                    {
                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        streamResource.IsUsed = true;
                        if (videoBox != null)
                        {
                            //await _meetingSdkWrapper.StartRemoteVideoRender(accountId, resourceId, videoBox.Handle,
                            //    (int)videoBox.Host.ActualWidth,
                            //    (int)videoBox.Host.ActualHeight);
                        }
                    }

                    result = subscribeCameraResult;
                }

                break;

            case MediaType.StreamMedia:
                break;

            case MediaType.File:
                break;

            case MediaType.WhiteBoard:
                break;

            case MediaType.RemoteControl:
                break;

            case MediaType.MediaTypeMax:
                break;
            }
            LayoutChanged(mediaType);
            return(result);
        }
        public async Task <MeetingResult <int> > Publish(MediaType mediaType, string deviceName)
        {
            ThrowIfPublishVerify();
            var      result = MeetingResult.Error <int>("未实现的媒体类型。");
            VideoBox videoBox;

            switch (mediaType)
            {
            case MediaType.Camera:

                var cameraParam = StreamParameterProviders.GetParameter <PublishCameraStreamParameter>(deviceName);

                PublishVideoModel publishCameraModel = cameraParam.GetPublishVideoModel();
                publishCameraModel.VideoSendModel.SourceName = deviceName;

                if (VideoBoxManager.TryGet(Participant.Account, VideoBoxType.Camera, mediaType, out videoBox))
                {
                    publishCameraModel.VideoSendModel.DisplayWindow = videoBox.Handle;
                }

                var publishCameraResult = await _meetingSdkWrapper.PublishCameraVideo(publishCameraModel);

                if (publishCameraResult.StatusCode == 0)
                {
                    var publishStreamResource = new StreamResource <IStreamParameter>
                    {
                        MediaType       = mediaType,
                        ResourceId      = publishCameraResult.Result,
                        SyncId          = publishCameraModel.AvSyncGroupId,
                        StreamParameter = cameraParam,
                        IsUsed          = true
                    };
                    Participant.Resources.Add(publishStreamResource);
                    if (videoBox != null)
                    {
                        videoBox.AccountResource.ResourceId = publishStreamResource.ResourceId;
                        videoBox.AccountResource.MediaType  = mediaType;

                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        //await _meetingSdkWrapper.StartLocalVideoRender(
                        //    publishStreamResource.ResourceId,
                        //    videoBox.Handle,
                        //    (int)videoBox.Host.ActualWidth,
                        //    (int)videoBox.Host.ActualHeight);
                    }
                }

                result = publishCameraResult;

                break;

            case MediaType.Microphone:

                PublishMicStreamParameter micParam = StreamParameterProviders.GetParameter <PublishMicStreamParameter>(deviceName);

                PublishAudioModel publishMicModel = micParam.GetPublishAudioModel();
                publishMicModel.AudioSendModel.SourceName = deviceName;

                MeetingResult <int> publishMicResult =
                    await _meetingSdkWrapper.PublishMicAudio(publishMicModel);

                if (publishMicResult.StatusCode == 0)
                {
                    StreamResource <IStreamParameter> publishStreamResource =
                        new StreamResource <IStreamParameter>
                    {
                        MediaType       = mediaType,
                        ResourceId      = publishMicResult.Result,
                        SyncId          = publishMicModel.AvSyncGroupId,
                        StreamParameter = micParam,
                        IsUsed          = true
                    };
                    Participant.Resources.Add(publishStreamResource);
                }

                result = publishMicResult;

                break;

            case MediaType.AudioCaptureCard:
            case MediaType.AudioDoc:

                PublishMicStreamParameter docMicParam = StreamParameterProviders.GetParameter <PublishMicStreamParameter>(deviceName);

                PublishAudioModel publishDocMicModel = docMicParam.GetPublishAudioModel();
                publishDocMicModel.AudioSendModel.SourceName = deviceName;

                MeetingResult <int> publishDocMicResult =
                    await _meetingSdkWrapper.PublishMicAudio(publishDocMicModel);

                if (publishDocMicResult.StatusCode == 0)
                {
                    StreamResource <IStreamParameter> publishStreamResource =
                        new StreamResource <IStreamParameter>
                    {
                        MediaType       = mediaType,
                        ResourceId      = publishDocMicResult.Result,
                        SyncId          = publishDocMicModel.AvSyncGroupId,
                        StreamParameter = docMicParam,
                        IsUsed          = true
                    };
                    Participant.Resources.Add(publishStreamResource);
                }

                result = publishDocMicResult;

                break;

            case MediaType.VideoDoc:
                PublishDataCardStreamParameter dataCardParam = StreamParameterProviders.GetParameter <PublishDataCardStreamParameter>(deviceName);

                PublishVideoModel publishDataCardModel = dataCardParam.GetPublishVideoModel();
                publishDataCardModel.VideoSendModel.SourceName = deviceName;

                if (VideoBoxManager.TryGet(Participant.Account, VideoBoxType.DataCard, mediaType, out videoBox))
                {
                    publishDataCardModel.VideoSendModel.DisplayWindow = videoBox.Handle;
                }

                MeetingResult <int> publishDataCardResult =
                    await _meetingSdkWrapper.PublishDataCardVideo(publishDataCardModel);

                if (publishDataCardResult.StatusCode == 0)
                {
                    StreamResource <IStreamParameter> publishStreamResource =
                        new StreamResource <IStreamParameter>
                    {
                        MediaType       = mediaType,
                        ResourceId      = publishDataCardResult.Result,
                        SyncId          = publishDataCardModel.AvSyncGroupId,
                        StreamParameter = dataCardParam,
                        IsUsed          = true
                    };


                    Participant.Resources.Add(publishStreamResource);
                    if (videoBox != null)
                    {
                        videoBox.AccountResource.ResourceId = publishStreamResource.ResourceId;
                        videoBox.AccountResource.MediaType  = mediaType;

                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        //await _meetingSdkWrapper.StartLocalVideoRender(
                        //    publishStreamResource.ResourceId,
                        //    videoBox.Handle,
                        //    (int)videoBox.Host.ActualWidth,
                        //    (int)videoBox.Host.ActualHeight);
                    }
                }

                result = publishDataCardResult;

                break;

            case MediaType.VideoCaptureCard:


                PublishWinCaptureStreamParameter winCapParam = StreamParameterProviders.GetParameter <PublishWinCaptureStreamParameter>(deviceName);

                PublishVideoModel publishWinCapModel = winCapParam.GetPublishVideoModel();
                publishWinCapModel.VideoSendModel.SourceName = "DesktopCapture";

                if (VideoBoxManager.TryGet(Participant.Account, VideoBoxType.WinCapture, mediaType, out videoBox))
                {
                    publishWinCapModel.VideoSendModel.DisplayWindow = videoBox.Handle;
                }

                MeetingResult <int> publishWinCapResult =
                    await _meetingSdkWrapper.PublishWinCaptureVideo(publishWinCapModel);

                if (publishWinCapResult.StatusCode == 0)
                {
                    StreamResource <IStreamParameter> publishStreamResource =
                        new StreamResource <IStreamParameter>
                    {
                        MediaType       = mediaType,
                        ResourceId      = publishWinCapResult.Result,
                        SyncId          = publishWinCapModel.AvSyncGroupId,
                        StreamParameter = winCapParam,
                        IsUsed          = true
                    };
                    Participant.Resources.Add(publishStreamResource);
                    if (videoBox != null)
                    {
                        videoBox.AccountResource.ResourceId = publishStreamResource.ResourceId;
                        videoBox.AccountResource.MediaType  = mediaType;

                        _eventAggregator.GetEvent <VideoBoxAddedEvent>().Publish(videoBox);

                        //await _meetingSdkWrapper.StartLocalVideoRender(
                        //    publishStreamResource.ResourceId,
                        //    videoBox.Handle,
                        //    (int)videoBox.Host.ActualWidth,
                        //    (int)videoBox.Host.ActualHeight);
                    }
                }

                result = publishWinCapResult;

                break;

            case MediaType.StreamMedia:
                break;

            case MediaType.File:
                break;

            case MediaType.WhiteBoard:
                break;

            case MediaType.RemoteControl:
                break;

            case MediaType.MediaTypeMax:
                break;
            }
            LayoutChanged(mediaType);
            return(result);
        }