主頁 > 服務(wù)與支持 > 開發(fā)平臺(tái) > 客戶端SDK參考 > Windows Native SDK > 會(huì)議 桌面協(xié)同與共享
更新時(shí)間:2019-12-10
描述
會(huì)議中,主講人和與會(huì)者可以進(jìn)行屏幕共享或程序共享。
前提條件:
業(yè)務(wù)流程
主講人共享屏幕
SDK并未對(duì)接口tsdk_app_share_set_owner的調(diào)用者進(jìn)行與角色限制,但實(shí)際應(yīng)用場景中,UI應(yīng)該僅對(duì)主講人才提供主動(dòng)“共享屏幕”入口。
//c code TSDK_RESULT ret; ret = tsdk_app_share_set_owner(confHandle, attendee, action); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share set owner failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
應(yīng)用程序在擁有主講人身份時(shí),收到此通知消息,UI應(yīng)自動(dòng)進(jìn)行后繼開始“共享屏幕”的處理流程,而不需要用戶確認(rèn)。
//c code case TSDK_E_CONF_EVT_AS_OWNER_CHANGE: { CHECK_POINTER(data); CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SHARING_SESSION, (WPARAM)param2, (LPARAM)data); break; } |
//c code TSDK_UINT32 confHandle = get_data_conf_handle(); TSDK_RESULT ret; ret = tsdk_app_share_start(confHandle, shareType); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share start failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_AS_STATE_CHANGE: { CHECK_POINTER(data); TSDK_S_CONF_AS_STATE_INFO* pResult = (TSDK_S_CONF_AS_STATE_INFO*)data; TSDK_S_CONF_AS_STATE_INFO* notifyInfo = new TSDK_S_CONF_AS_STATE_INFO; memset(notifyInfo, 0, sizeof(TSDK_S_CONF_AS_STATE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_CONF_AS_STATE_INFO), pResult, sizeof(TSDK_S_CONF_AS_STATE_INFO)); CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SHARING_STATE, (WPARAM)notifyInfo, (LPARAM)param2); break; } |
//c code case TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE: { CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SCREEN_DATA, NULL, NULL); break; } |
//c code TSDK_RESULT ret; ret = tsdk_app_share_get_screen_data(confHandle, screenData); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share get screen data failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
主講人邀請(qǐng)其他與會(huì)者共享屏幕
SDK并未對(duì)接口tup_conf_as_set_owner的調(diào)用者進(jìn)行與角色限制,但實(shí)際應(yīng)用場景中,UI應(yīng)該僅對(duì)主講人才提供“邀請(qǐng)其他與會(huì)者共享”入口;成功調(diào)用該接口后,原來擁有共享權(quán)限的用戶的共享權(quán)限會(huì)自動(dòng)取消,正在進(jìn)行的共享會(huì)停止。
//c code TSDK_RESULT ret; ret = tsdk_app_share_set_owner(confHandle, attendee, action); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share set owner failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
應(yīng)用程序在非主講人時(shí)收到此通知消息,并且共享者ID為自己,UI應(yīng)提示用戶收到共享邀請(qǐng),并提供“共享屏幕”和“拒絕共享”入口,若應(yīng)用程序支持“程序共享”,還應(yīng)該提供“程序共享”的選擇入口。
//c code case TSDK_E_CONF_EVT_AS_OWNER_CHANGE: { CHECK_POINTER(data); CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SHARING_SESSION, (WPARAM)param2, (LPARAM)data); break; } |
//c code TSDK_UINT32 confHandle = get_data_conf_handle(); TSDK_RESULT ret; ret = tsdk_app_share_start(confHandle, shareType); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share start failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
后繼步驟與“主講人共享屏幕”相同。
共享者主動(dòng)結(jié)束共享
//c code TSDK_RESULT ret; ret = tsdk_app_share_stop(confHandle); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share stop failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_AS_STATE_CHANGE: { CHECK_POINTER(data); TSDK_S_CONF_AS_STATE_INFO* pResult = (TSDK_S_CONF_AS_STATE_INFO*)data; TSDK_S_CONF_AS_STATE_INFO* notifyInfo = new TSDK_S_CONF_AS_STATE_INFO; memset(notifyInfo, 0, sizeof(TSDK_S_CONF_AS_STATE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_CONF_AS_STATE_INFO), pResult, sizeof(TSDK_S_CONF_AS_STATE_INFO)); CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SHARING_STATE, (WPARAM)notifyInfo, (LPARAM)param2); break; } |
主講人結(jié)束共享者共享
//c code TSDK_RESULT ret; ret = tsdk_app_share_set_owner(confHandle, attendee, action); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share set owner failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_AS_OWNER_CHANGE: { CHECK_POINTER(data); CDemoDataMeetingDlg* pDataMettingDlg = maindlg->GetDemoDataMeetingDlg(); CHECK_POINTER(pDataMettingDlg); ::PostMessage(pDataMettingDlg->GetSafeHwnd(), WM_DATACONF_MODULE_SHARING_SESSION, (WPARAM)param2, (LPARAM)data); break; } |
注意事項(xiàng)
無。
描述
會(huì)議過程中,與會(huì)者可以打開一個(gè)文檔進(jìn)行共享,以及關(guān)閉一個(gè)已經(jīng)共享的文檔或者取消打開一個(gè)已經(jīng)打開但未打開完成的文檔。
前提條件:
業(yè)務(wù)流程
打開共享文檔
SDK并未對(duì)接口tsdk_doc_share_open_document()的調(diào)用者進(jìn)行角色限制,實(shí)際應(yīng)用場景中,建議應(yīng)用程序UI僅對(duì)主講人或桌面共享權(quán)限所有者提供“共享文檔”入口,以減少不必要的交互。
//c code CString docmentPath; CFileDialog filedlg(TRUE); if (filedlg.DoModal()) { docmentPath = filedlg.GetPathName(); } unsigned int newdocid = 0; service_data_conf_ds_share_open_document(CTools::UNICODE2UTF(docmentPath).c_str(),&newdocid); int service_data_conf_ds_share_open_document(const char* file_path,unsigned int* doc_id) { TSDK_RESULT ret; ret = tsdk_doc_share_open_document(confHandle,file_path,TSDK_E_DOC_SHARE_SIZE,doc_id); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("share open document failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; } |
//c code case TSDK_E_CONF_EVT_DS_DOC_LOAD_START: { CHECK_POINTER(data); TSDK_S_DOC_BASE_INFO* pResult = (TSDK_S_DOC_BASE_INFO*)data; TSDK_S_DOC_BASE_INFO* notifyInfo = new TSDK_S_DOC_BASE_INFO; service_memset_s(notifyInfo, sizeof(TSDK_S_DOC_BASE_INFO), 0, sizeof(TSDK_S_DOC_BASE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_DOC_BASE_INFO), pResult, sizeof(TSDK_S_DOC_BASE_INFO)); CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(),WM_DATACONF_MODULE_DS_NEW,(WPARAM)notifyInfo,(LPARAM)param2); break; } |
//c code case TSDK_E_CONF_EVT_DS_DOC_NEW: { LOG_D_CALL_INFO("doc share new"); break; } |
//c code case TSDK_E_CONF_EVT_DS_DOC_PAGE_LOADED: { CHECK_POINTER(data); TSDK_S_DOC_PAGE_BASE_INFO* pResult = (TSDK_S_DOC_PAGE_BASE_INFO*)data; TSDK_S_DOC_PAGE_BASE_INFO* notifyInfo = new TSDK_S_DOC_PAGE_BASE_INFO; service_memset_s(notifyInfo, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), pResult, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(), WM_DATACONF_MODULE_DS_PAGE_LOADED, (WPARAM)notifyInfo, NULL); break; } |
//c code case TSDK_E_CONF_EVT_DS_DOC_PAGE_NEW: { LOG_D_CALL_INFO("doc share page new"); break; } |
收到此消息通知表示文檔加載并上傳服務(wù)器成功,可以進(jìn)行后繼操作,在此之前的步驟2至步驟5均為中間過程,UI可僅記錄狀態(tài)信息,不進(jìn)行界面刷新處理。
//c code case TSDK_E_CONF_EVT_DS_DOC_LOAD_FINISH: { CHECK_POINTER(data); TSDK_S_DOC_BASE_INFO* pResult = (TSDK_S_DOC_BASE_INFO*)data; TSDK_S_DOC_BASE_INFO* notifyInfo = new TSDK_S_DOC_BASE_INFO; service_memset_s(notifyInfo, sizeof(TSDK_S_DOC_BASE_INFO), 0, sizeof(TSDK_S_DOC_BASE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_DOC_BASE_INFO), pResult, sizeof(TSDK_S_DOC_BASE_INFO)); CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(),WM_DATACONF_MODULE_DS_DOCLOADED, (WPARAM)notifyInfo, (LPARAM)param2); break; } |
調(diào)用該接口后,當(dāng)前顯示的頁面將被切換到指定的文檔頁。如果指定的文檔ID為有效值而頁面ID為0,則切換到該文檔上次顯示的頁面。該函數(shù)有同步設(shè)置和非同步兩種,同步設(shè)置時(shí),其他所有與會(huì)者都會(huì)收到切換消息并顯示切換的頁面;非同步時(shí),只有本地發(fā)生變化,共享側(cè)應(yīng)該設(shè)置為同步。
//c code TSDK_RESULT ret; TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_DS; page_info.document_id = docId; page_info.page_index = pageIndex; ret = tsdk_doc_share_set_current_page(confHandle,&page_info,isSyn); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("set current page failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
代碼示例:
//c code case TSDK_E_CONF_EVT_DS_DOC_CURRENT_PAGE: { LOG_D_CALL_INFO("doc share current page"); break; } case TSDK_E_CONF_EVT_DS_DOC_CURRENT_PAGE_IND: { CHECK_POINTER(data); TSDK_S_DOC_PAGE_BASE_INFO* pResult = (TSDK_S_DOC_PAGE_BASE_INFO*)data; TSDK_S_DOC_PAGE_BASE_INFO* notifyInfo = new TSDK_S_DOC_PAGE_BASE_INFO; service_memset_s(notifyInfo, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), pResult, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(),WM_DATACONF_MODULE_DS_PAGE_IND,(WPARAM)notifyInfo,NULL); break; } |
后繼處理過程參見“切換文檔和頁面”描述。
關(guān)閉共享文檔
//c code TSDK_RESULT ret; ret = tsdk_doc_share_close_document(confHandle,docId); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("close document failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_DS_DOC_PAGE_DEL: { LOG_D_CALL_INFO("doc share page delete"); break; } |
//c code case TSDK_E_CONF_EVT_DS_DOC_DEL: { CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); CHECK_POINTER(data); TSDK_S_DOC_SHARE_DEL_DOC_INFO* pResult = (TSDK_S_DOC_SHARE_DEL_DOC_INFO*)data; TSDK_S_DOC_SHARE_DEL_DOC_INFO* notifyInfo = new TSDK_S_DOC_SHARE_DEL_DOC_INFO; service_memset_s(notifyInfo, sizeof(TSDK_S_DOC_SHARE_DEL_DOC_INFO), 0, sizeof(TSDK_S_DOC_SHARE_DEL_DOC_INFO)); memcpy_s(notifyInfo, sizeof(TSDK_S_DOC_SHARE_DEL_DOC_INFO), pResult, sizeof(TSDK_S_DOC_SHARE_DEL_DOC_INFO)); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(),WM_DATACONF_MODULE_DS_DELETE,(WPARAM)notifyInfo,(LPARAM)param2); break; } |
注意事項(xiàng)
無。
描述
會(huì)議過程中,與會(huì)者在不同的文檔和不同的頁面之間切換,以觀看不同的內(nèi)容。
前提條件:
業(yè)務(wù)流程
同步翻頁或切換文檔
//c code TSDK_RESULT ret; TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_DS; page_info.document_id = docId; page_info.page_index = pageIndex; ret = tsdk_doc_share_set_current_page(confHandle,&page_info,isSyn); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("set current page failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code TSDK_RESULT ret; TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_DS; page_info.document_id = docId; page_info.page_index = pageIndex; ret = tsdk_doc_share_set_current_page(confHandle,&page_info,isSyn); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("set current page failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_DS_DOC_DRAW_DATA_NOTIFY: { CDemoDocumentsShareDlg* pDocumentShareDlg = maindlg->GetDocumentDlg(); CHECK_POINTER(pDocumentShareDlg); ::PostMessage(pDocumentShareDlg->GetSafeHwnd(),WM_DATACONF_MODULE_DS_DRAW_DATA,NULL,NULL); break; } |
此通知消息在共享過程中頁面發(fā)生變更時(shí)就會(huì)上報(bào)。
//c code unsigned int bmpWidth; unsigned int bmpHeight; void* data = NULL; data = tsdk_doc_share_get_surface_bmp(confHandle,TSDK_E_COMPONENT_DS,&bmpWidth,&bmpHeight); if (NULL == data) { LOG_D_CALL_ERROR("get surface bmp failed."); return NULL; } return data; |
本地翻頁或切換文檔(本地瀏覽)
同步服務(wù)器頁面
通過此接口獲取當(dāng)前共享頁面信息,并通過后繼步驟2至步驟5保證觀看端頁面的立即更新。
//c code TSDK_S_DOC_PAGE_DETAIL_INFO info; service_data_conf_ds_share_get_syn_document_info(&info); m_docId = info.doc_page_info.document_id; m_pageNum = info.doc_page_info.page_index; int service_data_conf_ds_share_get_syn_document_info(TSDK_S_DOC_PAGE_DETAIL_INFO* sync_info) { TSDK_RESULT ret; ret = tsdk_doc_share_get_syn_document_info(confHandle,TSDK_E_COMPONENT_DS,sync_info); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("get syn document info failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; } |
//c code TSDK_RESULT ret; TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_DS; page_info.document_id = docId; page_info.page_index = pageIndex; ret = tsdk_doc_share_set_current_page(confHandle,&page_info,isSyn); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("set current page failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
注意事項(xiàng)
無。
描述
會(huì)議過程中,與會(huì)者通過白板與其他與會(huì)者進(jìn)行交流。
使用白板必然需要使用標(biāo)注功能,因標(biāo)注功能相對(duì)較獨(dú)立,且可以在多個(gè)業(yè)務(wù)場景下使用,所以本章節(jié)僅描述對(duì)白板文檔和頁面的管理操作,標(biāo)注相關(guān)操作參見“標(biāo)注”章節(jié)描述。
業(yè)務(wù)流程
新建白板
SDK并未對(duì)接口tsdk_whiteboard_new_document()的調(diào)用者進(jìn)行與角色限制,實(shí)際應(yīng)用場景中,建議應(yīng)用程序UI僅對(duì)主講人或桌面共享權(quán)限所有者提供“共享白板”入口,以減少不必要的交互。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); unsigned int* doc_id; /*Step 1:[Must]Create a new empty whiteboard document */ result = tsdk_whiteboard_new_document(conf_handle,doc_id); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Create a new empty whiteboard document failed. result=%#x", result); return SERVICE_E_WHITE_BOARD_SHARE_CREATE_NEW_FAILED; } |
//c code case TSDK_E_CONF_EVT_WB_DOC_NEW: { /*Create a new whiteboard document, all attendees can receive this message*/ service_handle_data_conf_whiteboard_doc_new_evt(conf_handle, type, value1, value2, data, size); break; } /** * @brief Create a new whiteboard document, all attendees can receive this message * * @param [in] unsigned int conf_handle data conference handle * @param [in] int type callback message type * @param [in] unsigned int value1 document ID * @param [in] unsigned int value2 Document new ID * @param [in] void* data NULL * @param [in] int size NULL * @retval void * * @attention: NA **/ void service_handle_data_conf_whiteboard_doc_new_evt(unsigned int conf_handle, int type, unsigned int value1, unsigned int value2, void *data, int size) { LOG_D_DATA_CONF_INFO("service_handle_data_conf_whiteboard_doc_new_evt"); (void)service_data_conf_notify_to_ui_proc(conf_handle, SERVICE_E_DATA_CONF_EVT_WB_DOC_NEW, value1, value2, NULL, NULL); return; } |
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_WB; page_info.document_id = current_document_id ; page_info.page_index = current_page_index ; /*Switch document or whiteboard page*/ result = tsdk_doc_share_set_current_page(conf_handle, &page_info, true); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Switch document or whiteboard page failed. result=%#x", result); return SERVICE_E_DOCUMENT_SHARE_SWITCH_FAILED; } |
//c code case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE: { /*Notify UI*/ }break; case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE_IND: { /*Notify UI*/ }break; |
共享側(cè)UI在完成空白白板創(chuàng)建后,應(yīng)該自動(dòng)新建第一個(gè)白板頁面,以減少不必要的用戶交互,提升用戶體驗(yàn)。后繼處理過程參見“新建白板頁”描述。
新建白板頁
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); /*Step 1:[Must]Create a new page*/ result = tsdk_whiteboard_new_page(conf_handle, doc_id, page_width, page_height, page_id); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Create a new page in specified whiteboard document failed. result=%#x", result); return SERVICE_E_WHITE_BOARD_SHARE_CREATE_NEW_PAGE_FAILED; } |
//c code case TSDK_E_CONF_EVT_WB_PAGE_NEW: { /*Create a new whiteboard document, all attendees can receive this message*/ service_handle_data_conf_whiteboard_doc_new_evt(conf_handle, type, value1, value2, data, size); break; } /** * @brief Create a new whiteboard document, all attendees can receive this message * * @param [in] unsigned int conf_handle data conference handle * @param [in] int type callback message type * @param [in] unsigned int value1 document ID * @param [in] unsigned int value2 Document new ID * @param [in] void* data NULL * @param [in] int size NULL * @retval void * * @attention: NA **/ void service_handle_data_conf_whiteboard_doc_new_evt(unsigned int conf_handle, int type, unsigned int value1, unsigned int value2, void *data, int size) { LOG_D_DATA_CONF_INFO("service_handle_data_conf_whiteboard_doc_new_evt"); (void)service_data_conf_notify_to_ui_proc(conf_handle, SERVICE_E_DATA_CONF_EVT_WB_DOC_NEW, value1, value2, NULL, NULL); return; } |
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; page_info.component_id = TSDK_E_COMPONENT_WB; page_info.document_id = current_document_id ; page_info.page_index = current_page_index ; /*Switch document or whiteboard page*/ result = tsdk_doc_share_set_current_page(conf_handle, &page_info, true); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Switch document or whiteboard page failed. result=%#x", result); return SERVICE_E_DOCUMENT_SHARE_SWITCH_FAILED; } |
//c code case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE: { /*Notify UI*/ }break case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE_IND: { /*Notify UI*/ }break |
//c code case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE: { /*Current page is turned, all attendees can receive this message*/ service_handle_data_conf_whiteboard_turn_page_evt(conf_handle, type, value1, value2, data, size); break; } /** * @brief Current page is turned, all attendees can receive this message * * @param [in] unsigned int conf_handle data conference handle * @param [in] int type callback message type * @param [in] unsigned int value1 document ID * @param [in] unsigned int value2 page ID * @param [in] void* data NULL * @param [in] int size NULL * @retval void * * @attention: NA **/ void service_handle_data_conf_whiteboard_turn_page_evt(unsigned int conf_handle, int type, unsigned int value1, unsigned int value2, void *data, int size) { LOG_D_DATA_CONF_INFO("service_handle_data_conf_whiteboard_turn_page_evt"); (void)service_data_conf_notify_to_ui_proc(conf_handle, SERVICE_E_DATA_CONF_EVT_WB_CURRENT_PAGE, value1, value2, NULL, NULL); return; } |
此通知消息在共享過程中白板頁面發(fā)生變更時(shí)就會(huì)上報(bào)。
//c code case TSDK_E_CONF_EVT_WB_DOC_DRAW_DATA_NOTIFY: { /*UI update notification, all attendees can receive this message*/ service_handle_data_conf_whiteboard_on_draw_data(conf_handle, type, value1, value2, data, size); break; } /** * @brief UI update notification, all attendees can receive this message * * @param [in] unsigned int conf_handle data conference handle * @param [in] int type callback message type * @param [in] unsigned int value1 document ID * @param [in] unsigned int value2 page ID * @param [in] void* data NULL * @param [in] int size NULL * @retval void * * @attention: NA **/ void service_handle_data_conf_whiteboard_on_draw_data(unsigned int conf_handle, int type, unsigned int value1, unsigned int value2, void *data, int size) { LOG_D_DATA_CONF_INFO("service_handle_data_conf_whiteboard_on_draw_data"); (void)service_data_conf_notify_to_ui_proc(conf_handle, SERVICE_E_DATA_CONF_EVT_WB_DRAW_DATA_NOTIFY, value1, value2, NULL, NULL); return; } |
//c code void* data = NULL; unsigned int conf_handle = get_data_conf_handle(); unsigned int* width; unsigned int* height; /*Step 1:[Must]Get document and whiteboard page image data*/ data = tsdk_doc_share_get_surface_bmp(conf_handle, TSDK_E_COMPONENT_WB, width, height); if(NULL == data) { LOG_D_DATA_CONF_ERROR("Get document and whiteboard page image data failed"); return NULL; } |
結(jié)束共享白板
case TSDK_E_CONF_EVT_WB_DOC_DEL: { /*Delete a whiteboard document, all attendees can receive this message*/ service_handle_data_conf_whiteboard_doc_del_evt(conf_handle, type, value1, value2, data, size); break; } /** * @brief Delete a whiteboard document, all attendees can receive this message * * @param [in] unsigned int conf_handle data conference handle * @param [in] int type callback message type * @param [in] unsigned int value1 document ID * @param [in] unsigned int value2 0 * @param [in] void* data NULL * @param [in] int size NULL * @retval void * * @attention: NA **/ void service_handle_data_conf_whiteboard_doc_del_evt(unsigned int conf_handle, int type, unsigned int value1, unsigned int value2, void *data, int size) { LOG_D_DATA_CONF_INFO("service_handle_data_conf_whiteboard_doc_del_evt"); (void)service_data_conf_notify_to_ui_proc(conf_handle, SERVICE_E_DATA_CONF_EVT_WB_DOC_DEL, value1, value2, NULL, NULL); return; } |
注意事項(xiàng)
無。
描述
在文檔共享或白板共享中,與會(huì)者間可以通過標(biāo)注功能在共享界面進(jìn)行遠(yuǎn)程交流。
業(yè)務(wù)流程
設(shè)置畫筆和畫刷
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_ANNOTATION_PEN_INFO new_pen_info = {0}; TSDK_S_ANNOTATION_PEN_INFO old_pen_info = {0}; TSDK_E_ANNOTATION_PEN_TYPE pen_type = TSDK_E_ANNOTATION_PEN_NORMAL; /*tup_pen_info comes from UI*/ new_pen_info.style = TSDK_E_ANNOTATION_PEN_STYLE_SOLID; new_pen_info.color = 0xFFFFFFAA; //0xRRGGBBAA new_pen_info.width = 1; /*Set pen information*/ result = tsdk_annotation_set_pen(conf_handle, TSDK_E_COMPONENT_WB, pen_type, &new_pen_info, &old_pen_info ); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Set pen information failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_SET_PEN_FAILED; } |
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_ANNOTATION_BRUSH_INFO new_brush_info = {0}; TSDK_S_ANNOTATION_BRUSH_INFO old_brush_info = {0}; /*the information of brush comes from UI*/ new_brush_info.style = TSDK_E_ANNOTATION_BRUSH_SOLID; new_brush_info.color = 0xFFFFFFAA; //0xRRGGBBAA /*Set paint brush information*/ result = tup_conf_annotation_set_brush(conf_handle, TSDK_E_COMPONENT_WB, &new_brush_info, &old_brush_info); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Set paint brush information failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_SET_BRUSH_FAILED; } |
創(chuàng)建幾何標(biāo)注
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TC_POINT tup_start_point = {0}; /*Start to create annotation*/ result = tsdk_annotation_create_start(conf_handle, TSDK_E_ANNOTATION_DRAWING, document_id, page_id, type, DS_ANNOTDRAWING_TYPE_FREEHAND, tup_start_point); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Start to create annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_START_CREATE_FAILED; } |
應(yīng)用程序界面應(yīng)在創(chuàng)建標(biāo)注過程中啟動(dòng)周期定時(shí)器,在檢查到鼠標(biāo)位置變化時(shí)調(diào)用此接口更新數(shù)據(jù),以呈現(xiàn)更優(yōu)的交互體驗(yàn)。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); CreateDrawingData data = {0}; /*Upodate annotation data*/ result = tsdk_annotation_create_update(conf_handle, TSDK_E_ANNOTATION_DRAWING, (void*)&data); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Upodate annotation data failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_UPDATE_FAILED; } |
若完成標(biāo)注創(chuàng)建,則此接口的第三個(gè)參數(shù)應(yīng)設(shè)置為0,否則設(shè)置為1。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); /*Finish creating annotation*/ result = tsdk_annotation_create_done(conf_handle, TSDK_E_COMPONENT_WB, false, NULL); if(TSDK_SUCCESS!= result) { LOG_D_DATA_CONF_ERROR("Finish creating annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_CREATE_FINISH_FAILED; } |
實(shí)際上,在標(biāo)注創(chuàng)建過程中,每次數(shù)據(jù)更新之后都會(huì)收到相應(yīng)的數(shù)據(jù)更新通知,當(dāng)前因流程圖限制,僅呈現(xiàn)在標(biāo)注創(chuàng)建完成后收到數(shù)據(jù)更新通知消息。
創(chuàng)建文字標(biāo)注
“文字標(biāo)注”與“幾何標(biāo)注”體驗(yàn)不同,其他與會(huì)者只有在“文字標(biāo)注”創(chuàng)建者完成標(biāo)注創(chuàng)建后才會(huì)顯示標(biāo)注內(nèi)容,即看不到文字的輸入過程。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; tsdk_memset_s(&page_info, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); TSDK_S_ANNOTATION_TEXT_INFO text_info; tsdk_memset_s(&text_info, sizeof(TSDK_S_ANNOTATION_TEXT_INFO), 0, sizeof(TSDK_S_ANNOTATION_TEXT_INFO)); TSDK_UINT32 annotation_id = 0; /*Create text annotation*/ result = tsdk_annotation_text_create(conf_handle, &page_info, &text_info, page_id, &tup_anno_text_info, &annotation_id ); if(TSDK_SUCCESS!= result) { LOG_D_DATA_CONF_ERROR("Create text annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_TEXT_CREATE_FAILED; } |
實(shí)際上,在標(biāo)注創(chuàng)建過程中,每次數(shù)據(jù)更新之后都會(huì)收到相應(yīng)的數(shù)據(jù)更新通知,當(dāng)前因流程圖限制,僅呈現(xiàn)在標(biāo)注創(chuàng)建完成后收到數(shù)據(jù)更新通知消息。
編輯文字標(biāo)注
與會(huì)者在文字標(biāo)注創(chuàng)建完成后,可以進(jìn)行編輯操作。
此接口所需的文字標(biāo)注ID通過“編輯標(biāo)注”中的“選中標(biāo)注”流程獲取。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; tsdk_memset_s(&page_info, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); TSDK_S_ANNOTATION_TEXT_INFO text_info; tsdk_memset_s(&text_info, sizeof(TSDK_S_ANNOTATION_TEXT_INFO), 0, sizeof(TSDK_S_ANNOTATION_TEXT_INFO)); TSDK_UINT32 annotation_id = 0; /*Get text information of the specified annotation*/ result = tsdk_annotation_text_get_info(conf_handle, &page_info, annotation_id, &text_info); if(TSDK_SUCCESS!= result) { LOG_D_DATA_CONF_ERROR("Get text information of the specified annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_GET_TEXT_INFO_FAILED; } |
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; tsdk_memset_s(&page_info, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); TSDK_S_ANNOTATION_TEXT_INFO text_info; tsdk_memset_s(&text_info, sizeof(TSDK_S_ANNOTATION_TEXT_INFO), 0, sizeof(TSDK_S_ANNOTATION_TEXT_INFO)); TSDK_UINT32 annotation_id = 0; TSDK_BOOL is_redraw = 0; /*Create text annotation*/ result = tsdk_annotation_text_update(conf_handle, &page_info, annotation_id , &text_info, is_redraw); if(TSDK_SUCCESS!= result) { LOG_D_DATA_CONF_ERROR("Update text annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_UPDATE_TEXT_INFO_FAILED; } |
注意事項(xiàng)
無。
描述
在屏幕共享、文檔共享或白板共享中,與會(huì)者可以對(duì)共享過程中創(chuàng)建的標(biāo)注進(jìn)行選中、編輯或刪除操作。
前提條件:
業(yè)務(wù)流程
選中標(biāo)注
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_ANNOTATION_HIT_TEST_POINT_INFO hit_test_point_info; tsdk_memset_s(&hit_test_point_info, sizeof(TSDK_S_ANNOTATION_HIT_TEST_POINT_INFO), 0, sizeof(TSDK_S_ANNOTATION_HIT_TEST_POINT_INFO)); TSDK_UINT32 select_annotation_id = 0; TSDK_E_ANNOTATION_HIT_TEST_CODE hit_test_code = TSDK_E_ANNOTATION_HIT_TEST_BUTT; TSDK_UINT32 annotation_type = 0; /*Test whether a point falls on the annotation*/ result = tsdk_annotation_hit_test_point(conf_handle, &hit_test_point_info, select_annotation_id, hit_test_code , annotation_type ); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Test whether a point falls on the annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_TEST_POINT_FAILED; } TSDK_UINT32 count = 0; TSDK_UINT32* annotation_id_list = 0; /*Test annotation in a rect*/ result = tsdk_annotation_hit_test_rect(conf_handle, &hit_test_point_info, &annotation_id_list , &count ); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Test annotation in a rect failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_TEST_IN_RECT_FAILED; } |
設(shè)置選中狀態(tài),可以設(shè)置為選中狀態(tài)或非選中狀態(tài),可以設(shè)置立刻刷新界面或不刷新界面。設(shè)置為立即刷新時(shí),若為選中狀態(tài),界面會(huì)收到數(shù)據(jù)更新的通知,被選中的標(biāo)注邊框上會(huì)多出8個(gè)選中框;若為非選中狀態(tài)后,邊框消失。該接口只會(huì)對(duì)自己的界面產(chǎn)生影響,不會(huì)影響其他與會(huì)者。
//c code TSDK_RESULT result = 0; unsigned int conf_handle = get_data_conf_handle() TSDK_S_ANNOTATION_SELECT_INFO select_info; tsdk_memset_s(&select_info, sizeof(TSDK_S_ANNOTATION_SELECT_INFO), 0, sizeof(TSDK_S_ANNOTATION_SELECT_INFO)); /*Test annotation in a rect*/ result = tsdk_annotation_set_select(conf_handle, &select_info, is_redraw); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Set annotation status failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_SET_STATUS_FAILED; } |
編輯標(biāo)注
標(biāo)注被選中后,與會(huì)者可以進(jìn)行拖動(dòng)或拉伸,以改變標(biāo)注的位置或形狀。
此接口可以對(duì)選中的多個(gè)標(biāo)注同時(shí)開始編輯,編輯過程中,被選中的標(biāo)注會(huì)一同被移動(dòng)或被拉伸。
//c code TUP_RESULT result = TUP_FAIL; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_DOC_PAGE_BASE_INFO page_info; tsdk_memset_s(&page_info, sizeof(TSDK_S_DOC_PAGE_BASE_INFO), 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO)); TC_POINT tup_point_info = {0}; /*Start to edit the annotation*/ result = tsdk_annotation_edit_start(conf_handle, IID_COMPONENT_WB, document_id, page_id, annotation_id, count, current_anno_id, (DS_HITTEST_CODE)edit_type, tup_point_info); if(TC_OK != result) { LOG_D_DATA_CONF_ERROR("Start to edit the annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_EDIT_START_FAILED; } |
應(yīng)用程序界面應(yīng)在編輯標(biāo)注過程中啟動(dòng)周期定時(shí)器,在檢查到鼠標(biāo)位置變化時(shí)調(diào)用此接口更新數(shù)據(jù),以呈現(xiàn)更優(yōu)的交互體驗(yàn)。
//c code TSDK_RESULT result = TUP_FAIL; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_POINT current_point; tsdk_memset_s(¤t_point, sizeof(TSDK_S_POINT), 0, sizeof(TSDK_S_POINT)); TSDK_E_COMPONENT_ID component_id; /*Update the annotation*/ result = tsdk_annotation_edit_update(conf_handle, component_id, ¤t_point); if(TC_OK != result) { LOG_D_DATA_CONF_ERROR("Update the annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_EDIT_UPDATE_FAILED; } |
若完成標(biāo)注編輯,則此接口的第三個(gè)參數(shù)應(yīng)設(shè)置為0,否則設(shè)置為1。
//c code TSDK_RESULT result = TUP_FAIL; unsigned int conf_handle = get_data_conf_handle(); /*Finish creating annotation*/ result = tsdk_annotation_edit_done(conf_handle, TSDK_E_COMPONENT_WB, is_cancel); if(TC_OK != result) { LOG_D_DATA_CONF_ERROR("Finish creating annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_CREATE_FINISH_FAILED; } |
實(shí)際上,在標(biāo)注編輯過程中,每次數(shù)據(jù)更新之后都會(huì)收到相應(yīng)的數(shù)據(jù)更新通知,當(dāng)前因流程圖限制,僅呈現(xiàn)在標(biāo)注編輯完成后收到數(shù)據(jù)更新通知消息。
刪除標(biāo)注
此接口可以對(duì)選中的多個(gè)標(biāo)注同時(shí)開始刪除,應(yīng)用程序也可以實(shí)現(xiàn)對(duì)標(biāo)注ID的記錄管理,給用戶提供刪除“自己創(chuàng)建的標(biāo)注”、“其他人創(chuàng)建的標(biāo)注”和“所有標(biāo)注”功能入口。
//c code TSDK_RESULT result; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_ANNOTATION_DELETE_INFO delete_info; tsdk_memset_s(&delete_info, sizeof(TSDK_S_ANNOTATION_DELETE_INFO), 0, sizeof(TSDK_S_ANNOTATION_DELETE_INFO)); /*Delete the annotation*/ result = tsdk_annotation_delete_annotation(conf_handle, &delete_info); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Delete the annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_DELETE_FAILED; } |
注意事項(xiàng)
無。
描述
會(huì)議過程中,與會(huì)者進(jìn)行激光點(diǎn)的開啟、移動(dòng)和停止操作。
前提條件:
業(yè)務(wù)流程
開啟激光的接口中用到的坐標(biāo)都是相對(duì)于頁面左上角的TWIPS單位坐標(biāo),向右向下為正。
//c code TSDK_RESULT result; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_ANNOTATION_LASER_POINTER_INFO laser_pointer_info; tsdk_memset_s(&laser_pointer_info,sizeof(TSDK_S_ANNOTATION_LASER_POINTER_INFO),0,sizeof(TSDK_S_ANNOTATION_LASER_POINTER_INFO)); /*Start to use laser point in annotation.*/ result = tsdk_annotation_laser_pointer_start(conf_handle, TSDK_E_COMPONENT_WB,&laser_pointer_info ); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Start to use laser pointer in annotation failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_START_LASER_POINTER_FAILED; } |
應(yīng)用程序界面應(yīng)在移動(dòng)激光點(diǎn)過程中啟動(dòng)周期定時(shí)器,在檢查到鼠標(biāo)位置變化時(shí)調(diào)用此接口更新數(shù)據(jù),以呈現(xiàn)更優(yōu)的交互體驗(yàn)。
//c code TSDK_RESULT result; unsigned int conf_handle = get_data_conf_handle(); TSDK_S_POINT point; tsdk_memset_s(&point, sizeof(TSDK_S_POINT), 0, sizeof(TSDK_S_POINT)); /*Move the laser pointer to the destination.*/ result = tsdk_annotation_laser_pointer_moveto(conf_handle, TSDK_E_COMPONENT_WB, &point); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Move the laser pointer failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_MOVE_LASER_POINTER_FAILED; } |
//c code TSDK_RESULT result; unsigned int conf_handle = get_data_conf_handle(); /*Stop the laser pointer.*/ result = tsdk_annotation_laser_pointer_stop(conf_handle, TSDK_E_COMPONENT_WB); if(TSDK_SUCCESS != result) { LOG_D_DATA_CONF_ERROR("Stop the laser pointer failed. result=%#x", result); return SERVICE_E_SHARE_ANNOTATION_STOP_LASER_POINTER_FAILED; } |
實(shí)際上,在激光點(diǎn)移動(dòng)過程中,每次數(shù)據(jù)更新之后都會(huì)收到相應(yīng)的數(shù)據(jù)更新通知,當(dāng)前因流程圖限制,僅呈現(xiàn)在激光點(diǎn)結(jié)束后收到數(shù)據(jù)更新通知消息。
注意事項(xiàng)
無。
描述
會(huì)議過程中,某一與會(huì)者可以發(fā)送即時(shí)消息給其他所有與會(huì)者。
業(yè)務(wù)流程
//c code TSDK_RESULT ret; ret = tsdk_send_chat_msg_in_conference(confHandle, chatMsgInfo); if (TSDK_SUCCESS != ret) { LOG_D_CALL_ERROR("send chat msg failed. result=%#x", ret); return -1; } return TSDK_SUCCESS; |
//c code case TSDK_E_CONF_EVT_RECV_CHAT_MSG: { /*Notify UI*/ } |
注意事項(xiàng)
當(dāng)前僅提供公共消息的開放能力。