智慧服务,成就美好体验 项目咨询

主页 > 服务与支持 > 开发平台 > 客户端SDK参考 > Windows Native SDK > 会议 会议控制

入门使用

会议控制

更新时间:2019-11-20

退出和结束会议

描述

普通与会者和主席均可在会议中主动退出会议,主席可以结束会议。

说明: 

若主席退出会议,则会议中无主席,预约会议时,原主席可以通过主席接入信息重新加入会议获取主席;当会议中无任何与会者时,会议也会自动结束。

与会者已在会议中。

业务流程

退出会议

图1 退出会议流程 
  1. 普通与会者或主席侧UI调用tsdk_leave_conference()主动退出会议。
    说明: 

    在主动离开会议过程中,sdk层会主动挂断通话,然后才离开会议。

    代码示例:
    //c code
    TSDK_RESULT ret;
    ret = tsdk_leave_conference(confHandle);
    if (TSDK_SUCCESS != ret)
    {
        LOG_D_CALL_ERROR("leave conf failed. result=%#x", ret);
        return -1;
    }
    return TSDK_SUCCESS;
    
     
  2. 普通与会者或主席侧SDK在收到“退出会议”请求的响应后,向UI上报删除呼叫id事件TSDK_E_CALL_EVT_CALL_DESTROY。
    代码示例:
    //c code
    case TSDK_E_CALL_EVT_CALL_DESTROY:
    {
         CHECK_POINTER(data);
         TSDK_S_CALL_INFO* callInfo = (TSDK_S_CALL_INFO*)data;
         TSDK_S_CALL_INFO* notifyInfo = new TSDK_S_CALL_INFO;
         memset(notifyInfo, 0, sizeof(TSDK_S_CALL_INFO));
         memcpy_s(notifyInfo, sizeof(TSDK_S_CALL_INFO), callInfo, sizeof(TSDK_S_CALL_INFO));
    
         ::PostMessage(maindlg->GetSafeHwnd(), WM_CALL_END, (WPARAM)notifyInfo, NULL);
         break;
    }
    
     
  3. 其他与会者侧SDK收到会议成员列表刷新通知,向UI上报会议成员列表刷新事件TSDK_E_CONF_EVT_INFO_AND_STATUS_UPDATE,UI刷新会议成员列表。
    说明: 

    详细流程参见“更新会议状态信息和与会者列表”描述。

 

结束会议

图2 结束会议流程 
  1. 主席侧UI调用tsdk_end_conference()结束会议。
    说明: 

    应用程序界面在关闭会议时应为主席提供“退出会议”和“结束会议”的选择入口。

    代码示例:
    //c code
    TSDK_RESULT ret;
    ret = tsdk_end_conference(confHandle);
    if (TSDK_SUCCESS != ret)
    {
        LOG_D_CALL_ERROR("end conf failed. result=%#x", ret);
        return -1;
    }
    return TSDK_SUCCESS;
    
     
  2. 其他与会者侧SDK收到会议结束通知,向UI上报会议结束事件TSDK_E_CONF_EVT_CONF_END_IND,UI提示用户会议结束。

注意事项

无。

基础会控操作

描述

在会议中进行基础的会议控制操作。

业务流程

基础会议控制

图3 基础会议控制流程 
  1. UI调用会议基础控制接口(如表1),实现会议控制相关操作。
    表1 会议控制相关操作

    会控类型

    接口

    权限

    说明

    闭音会议

    tsdk_mute_conference

    主席

    设置会议闭音后,除主席外,其他所有与会者均不可说(只可听)。

    添加与会者

    tsdk_add_attendee

    主席

    支持邀请一个或多个与会者。

    重拨与会者

    tsdk_redial_attendee

    主席

    -

    挂断与会者

    tsdk_hang_up_attendee

    主席

    挂断在会议中的与会者.

    删除与会者

    tsdk_remove_attendee

    主席

    踢出与会者(正在会议中的)、移除已离会的与会者和取消正在邀请的与会者。

    闭音与会者

    tsdk_mute_attendee

    主席

    普通与会者

    设置闭音后,该与会者不可说(只听)。

    会议主席在会议中设置或取消其他与会者闭音,普通与会者设置或取消自己闭音。

    举手

    tsdk_set_handup

    主席

    普通与会者

    会议主席在会议中取消其他与会者举手,所有与会者设置或取消自己举手。

    设置会议视频模式

    tsdk_set_video_mode

    主席

    在CloudEC解决方案下,支持的视频会议模式有“广播与会者模式”、“声控模式”和“自由讨论模式”。

    观看与会者

    tsdk_watch_attendee

    主席

    普通与会者

    AVC 会议:只需要指定待选看的与会者号码,每次指定选看一个与会者。

    SVC会议:

    1. 除指定待选看的与会者号码外,还应该指定"SVC Label",以及待选看的分辨率(宽和高),且“SVC Label”与“分辨率”必须与“绑定SVC视频窗口”时填写的参数相对应。
    2. 更新选看时,需要全量指定所有选看信息(一大多少)。
    3. 若指定的待选看与会者号码为空(仅支持大窗口),则所选看的与会者由系统自动推送。

    广播与会者

    tsdk_broadcast_attendee

    主席

    会议视频模式为“广播与会者模式”时主席可以指定广播与会者。

    申请主席

    tsdk_request_chairman

    普通与会者

    -

    释放主席

    tsdk_release_chairman

    主席

    -

    延长会议

    tsdk_postpone_conference

    主席

    -

    设置主讲人

    tsdk_set_presenter

    主席

    会议主讲人

    会议类型为TSDK_E_CONF_MEDIA_VOICE_DATA或TSDK_E_CONF_MEDIA_VIDEO_DATA支持。

    申请主讲人

    tsdk_request_presenter

    与会者

    会议类型为TSDK_E_CONF_MEDIA_VOICE_DATA或TSDK_E_CONF_MEDIA_VIDEO_DATA支持。

    设置会议录播

    tsdk_set_record_broadcast

    主席

    -

    设置会议直播

    tsdk_set_live_broadcast

    主席

    -

    代码示例:
    //c code
    /* 闭音会场 */
    TSDK_RESULT ret;
    ret = tsdk_mute_conference(confHandle, isMute);
    if (TSDK_SUCCESS != ret)
    {
        LOG_D_CALL_ERROR("mute conference failed. result=%#x", ret);
        return -1;
    }
    return TSDK_SUCCESS;
    
     
  2. SDK在收到会控请求的响应后,向UI上报会控操作结果事件TSDK_E_CONF_EVT_CONFCTRL_OPERATION_RESULT。
    代码示例:
    //c code
    case TSDK_E_CONF_EVT_CONFCTRL_OPERATION_RESULT:
    {
         CHECK_POINTER(data);
         TSDK_S_CONF_OPERATION_RESULT* pResult = (TSDK_S_CONF_OPERATION_RESULT*)data;
         TSDK_S_CONF_OPERATION_RESULT* notifyInfo = new TSDK_S_CONF_OPERATION_RESULT;
         memset(notifyInfo, 0, sizeof(TSDK_S_CONF_OPERATION_RESULT));
         memcpy_s(notifyInfo, sizeof(TSDK_S_CONF_OPERATION_RESULT), pResult, sizeof(TSDK_S_CONF_OPERATION_RESULT));
    
         if(TSDK_SUCCESS != notifyInfo->reason_code)
         { 
    	maindlg->MessageBox(_T("operation failed!"));
         }
    
         if (TSDK_SUCCESS == notifyInfo->reason_code)
         {
             if(TSDK_E_CONF_SET_PRESENTER  == notifyInfo->operation_type)
             { 
                CDemoDataMeetingDlg* dataMeetingDlg = maindlg->GetDemoDataMeetingDlg();
                CHECK_POINTER(dataMeetingDlg);
                dataMeetingDlg->SetPresenter(false);
             }
          }
          break;
    }
    
     
  3. 主席侧和其他与会者侧SDK收到会议成员列表刷新通知,向UI上报会议成员列表刷新事件TSDK_E_CONF_EVT_INFO_AND_STATUS_UPDATE,UI刷新会议页面。
    说明: 

    详细流程参见“更新会议状态信息和与会者列表”描述。

注意事项

无。

更新会议状态信息和与会者列表

描述

会议过程中,会议状态或与会者成员状态发生变化时,服务器会推送变更通知,应用程序界面应刷新相应的状态以提示用户。

说明: 
  1. 会议状态当前包括锁定状态、闭音状态和是否录播状态;
  2. 会议成员状态当前包括与会者加入、退出、挂断、闭音、举手和角色变更。

主席和与会者均已在会议中。

业务流程

图4 更新会议状态信息和与会者列表流程 
  1. SDK在收到服务器的与会者列表更新通知后,向UI上报与会者列表更新事件TSDK_E_CONF_EVT_INFO_AND_STATUS_UPDATE。
    说明: 

    事件对应的数据结构TSDK_S_CONF_STATUS_INFO中:

    • is_record,表示会场录音状态,为true时,应用程序界面应提示与会者当前处于录音状态;
    • is_all_mute,表示会场静音状态,为true时,应用程序界面应提示与会者当前处于会场闭音状态,除主席外,均可听不可说;
    • subject,会议主题,不为空时,应用程序界面应显示此主题,在会议创建时已确定,首次获取后,不会再有变更;
    • is_hd_conf,高清视频会议,为true时,会议视频为高清视频;
    • conf_media_type,会议媒体类型,参考结构体TSDK_E_CONF_MEDIA_TYPE;
    • conf_state,会议状态,参考结构体TSDK_E_CONF_STATE;
    • update_type,表示成员更新方式,支持无更新、全量更新、增量增加、增量修改和增量删除,目前以全量同步的方式进行更新;
    • attendee_num,当前会议中的与会者个数;
    • attendee_list,与会者的详细信息,包括用户标识、名称、号码、闭音状态、静音状态、举手状态、用户状态、角色和支持的媒体类型,应用程序界面需要根据相应字段显示与会者的信息和状态;
    • is_live_broadcast,表示会场直播状态,为true时,应用程序应提示与会者当前出于直播状态 ;
    • is_support_live_broadcast,表示会场是否支持直播 ;
    • is_support_record_broadcast,表示会场是否支持录播.
    代码示例:
    //c code
    case TSDK_E_CONF_EVT_INFO_AND_STATUS_UPDATE:
    {
         CHECK_POINTER(data);
         TSDK_S_CONF_STATUS_INFO* pResult = (TSDK_S_CONF_STATUS_INFO*)data;
         TSDK_S_CONF_STATUS_INFO* notifyInfo = new TSDK_S_CONF_STATUS_INFO;
         memset(notifyInfo, 0, sizeof(TSDK_S_CONF_STATUS_INFO));
         memcpy_s(notifyInfo, sizeof(TSDK_S_CONF_STATUS_INFO), pResult, sizeof(TSDK_S_CONF_STATUS_INFO));
    
         unsigned int attrndsnumber = pResult->attendee_num;
         notifyInfo->attendee_list = NULL;
         notifyInfo->attendee_list = (TSDK_S_ATTENDEE*)malloc(attrndsnumber*sizeof(TSDK_S_ATTENDEE));
         if (NULL == notifyInfo->attendee_list)
         {
             return;
         }
         (void)memset(notifyInfo->attendee_list, 0, attrndsnumber*sizeof(TSDK_S_ATTENDEE));
          TSDK_S_ATTENDEE* pTempAttendee = notifyInfo->attendee_list;
          for (unsigned int i = 0; i < attrndsnumber; i++)
          {
               if (pTempAttendee)
               {
                  (void)strncpy_s(pTempAttendee->status_info.participant_id, TSDK_D_MAX_PARTICIPANTID_LEN+1, pResult->attendee_list[i].status_info.participant_id, _TRUNCATE);
                  (void)strncpy_s(pTempAttendee->base_info.display_name, TSDK_D_MAX_DISPLAY_NAME_LEN+1, pResult->attendee_list[i].base_info.display_name, _TRUNCATE);
                  (void)strncpy_s(pTempAttendee->base_info.number, TSDK_D_MAX_NUMBER_LEN+1, pResult->attendee_list[i].base_info.number, _TRUNCATE);
                   pTempAttendee->base_info.role = (TSDK_E_CONF_ROLE)pResult->attendee_list[i].base_info.role;
                   pTempAttendee->status_info.is_mute = pResult->attendee_list[i].status_info.is_mute;
                   pTempAttendee->status_info.is_handup = pResult->attendee_list[i].status_info.is_handup;
                   pTempAttendee->status_info.state = (TSDK_E_CONF_PARTICIPANT_STATUS)pResult->attendee_list[i].status_info.state;
                   pTempAttendee->status_info.has_camera = pResult->attendee_list[i].status_info.has_camera;
                   pTempAttendee->status_info.is_present = pResult->attendee_list[i].status_info.is_present;
                   pTempAttendee->status_info.is_self = pResult->attendee_list[i].status_info.is_self;
                }
                else
                {
                   break;
                }
                pTempAttendee++;
            }
    
            if (TSDK_E_CONF_MEDIA_VOICE == notifyInfo->conf_media_type)
            {
                CDemoAudioMeetingDlg* pAudioMettingDlg = maindlg->GetDemoAudioMeetingDlg();
                CHECK_POINTER(pAudioMettingDlg);
                ::PostMessage(pAudioMettingDlg->GetSafeHwnd(), WM_CONF_CTRL_INFO_AND_STATUS_UPDATE, (WPARAM)notifyInfo, (LPARAM)param1);
            }
            else if (TSDK_E_CONF_MEDIA_VIDEO == notifyInfo->conf_media_type)
            {
                CDemoVideoMeetingDlg* pVideoMettingDlg = maindlg->GetDemoVideoMeetingDlg();
                CHECK_POINTER(pVideoMettingDlg);
                ::PostMessage(pVideoMettingDlg->GetSafeHwnd(), WM_CONF_CTRL_INFO_AND_STATUS_UPDATE, (WPARAM)notifyInfo, (LPARAM)param1);
            }
            else if (TSDK_E_CONF_MEDIA_VOICE_DATA == notifyInfo->conf_media_type || TSDK_E_CONF_MEDIA_VIDEO_DATA == notifyInfo->conf_media_type)
            {
                CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg();
                CHECK_POINTER(pDataMettingDlg);
                ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_CONF_CTRL_INFO_AND_STATUS_UPDATE, (WPARAM)notifyInfo, (LPARAM)param1);
            }
            break;
        }
    
     

注意事项

无。