暖暖视频免费观**,国产免费美女被艹视频,毛片一级毛片,不卡三级

智慧服務(wù),成就美好體驗(yàn) 項(xiàng)目咨詢

主頁 > 服務(wù)與支持 > 開發(fā)平臺(tái) > 客戶端SDK參考 > iOS Native SDK > 會(huì)議 桌面協(xié)同與共享

入門使用

桌面協(xié)同與共享

更新時(shí)間:2019-11-20

開始和結(jié)束屏幕共享

說明: 

iOS 屏幕共享要求操作系統(tǒng) iOS 12.0 及以上版本,使用功能時(shí),需要啟動(dòng)系統(tǒng)的屏幕錄制功能,因此需要配置相關(guān)工程,詳見會(huì)議中屏幕共享進(jìn)行配置。

描述

會(huì)議中,主講人和與會(huì)者可以進(jìn)行屏幕共享。

前提條件:

  1. 加入數(shù)據(jù)會(huì)議成功。
  2. 加載屏幕/程序共享模塊成功。

業(yè)務(wù)流程

主講人共享屏幕

圖1 主講人共享屏幕流程 
  1. 主講人選擇共享本端屏幕,UI調(diào)用tsdk_app_share_set_owner()接口設(shè)置自己為共享權(quán)限擁有者。
    說明: 

    SDK并未對接口tsdk_app_share_set_owner的調(diào)用者進(jìn)行與角色限制,但實(shí)際應(yīng)用場景中,UI應(yīng)該僅對主講人才提供主動(dòng)“共享屏幕”入口。

    代碼示例:
    //oc code 
    - (BOOL)inviteDataShareWithNumber:(NSString *)number
    {    
        TSDK_RESULT result = tsdk_app_share_set_owner(_confHandle, (TSDK_CHAR*)[number UTF8String], TSDK_E_CONF_AS_ACTION_ADD);        
        return result;
    }
     
  2. 主講人側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)共享權(quán)限擁有者變更通知消息TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新共享者信息。
    說明: 

    TSDK_E_CONF_EVT_AS_OWNER_CHANGE通知中攜帶的共享類型為TSDK_E_CONF_AS_ACTION_ADD,并且共享者ID為自己,調(diào)起系統(tǒng)屏幕錄制界面,并選擇當(dāng)前程序然后點(diǎn)擊“開始錄制”。

    代碼示例:
    //oc code
    - (void)startReplayKitBroadcast {
        dispatch_async(dispatch_get_main_queue(), ^{
            DDLogInfo(@"enter startReplayKitBroadcast ");
            if (@available(iOS 12, *)) {
                NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                BOOL isNeedSetpreferredExtension = [userDefaults boolForKey:@"ScreenShareFlag"];
                NSString *mainBundleId = [[NSBundle mainBundle]bundleIdentifier];
                NSString *extensionId = [mainBundleId stringByAppendingString:@".ScreenShareExtension"];
                if (isNeedSetpreferredExtension) {
                    self.broadcastPickerView.preferredExtension = extensionId;
                }
                self.broadcastPickerView.showsMicrophoneButton = NO;
    
                for (UIView *view in self.broadcastPickerView.subviews) {
                    if ([view isKindOfClass:[UIButton class]]) {
                        [(UIButton *)view sendActionsForControlEvents:UIControlEventTouchDown];
                    }
                }
            }
        });
    }
     
  3. UI調(diào)用tsdk_app_share_set_virtual_view_info()接口,設(shè)置虛擬顯示器信息。
    說明: 

    1、在一個(gè)全局的對象的初始化方法中,調(diào)用initScreenShareManager初始化screenSharemanage對象;

    2、當(dāng)點(diǎn)擊“開始錄制”后,會(huì)上報(bào)系統(tǒng)錄屏狀態(tài),當(dāng)狀態(tài)state == 1時(shí),且自己已經(jīng)加入數(shù)據(jù)會(huì)議中,開始調(diào)用設(shè)置虛擬顯示器信息接口tsdk_app_share_set_virtual_view_info(),如果不在數(shù)據(jù)會(huì)議中,則通知系統(tǒng)關(guān)閉屏幕錄制功能。

    3、錄制開始后,系統(tǒng)會(huì)不停的上報(bào)屏幕數(shù)據(jù)上來,調(diào)用processImage()方法,將圖片數(shù)據(jù)的相關(guān)信息轉(zhuǎn)換后傳給服務(wù)器。

    //oc code
    - (void)initScreenShareManager {
        DDLogInfo(@"enter initScreenShareManager ");
        NSString *appGroup = @"group.eSpaceMclientV2";
        self.screenShareManager = [[ScreenShareManager alloc]initWithAppGroupIdentifier:appGroup];
        [self.screenShareManager listenForMessageWithIdentifier:@"screenshare" listener:^(id messageObject) {
    
            NSDictionary *dir = [messageObject valueForKey:@"screendata"];
            [self processImage:dir];
        }];
        [self.screenShareManager listenForMessageWithIdentifier:@"screenShareStateChange" listener:^(id messageObject) {
            long state = [[messageObject valueForKey:@"state"] longValue];
            if (state == 1) {
                if (self.isJoinDataConfSuccess) {
                    self.mIsScreenSharing = YES;
                    [self startDataConfAsPre];
                    [self startDataShare];
    
                } else {
                    NSError *error = [[NSError alloc] initWithDomain:@"ScreenShare" code:-1 userInfo:@{NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"the meeting is unavailable", nil)}];
                    [self.screenShareManager passMessageObject:@{@"result" : error} identifier:@"StopBroadcast"];
                }
    
            } else if (state == 0) {
                [self confStopReplayKitBroadcast];
            }
        }];
    }
    
    - (void) startDataConfAsPre {
        DDLogInfo(@"enter startDataConfAsPre _mIsScreenSharing: %d _mWidthPixels: %d _mHeightPixels: %d " , self.mIsScreenSharing, self.mWidthPixels , self.mHeightPixels);
        self.mIsStartScreenShareDelayed = NO;
        if (self.mWidthPixels == 0 || self.mHeightPixels == 0) {
            self.mIsStartScreenShareDelayed = YES;
            return;
        }
        TSDK_S_CONF_AS_VIRTUAL_VIEW_INFO virtual_view_info;
        memset(&virtual_view_info, 0, sizeof(TSDK_S_CONF_AS_VIRTUAL_VIEW_INFO));
        virtual_view_info.width = _mWidthPixels;
        virtual_view_info.height = _mHeightPixels;
        virtual_view_info.bit_count = 32;
    
        tsdk_app_share_set_virtual_view_info(_confHandle, &virtual_view_info);
    }
    
    -(void)processImage:(NSDictionary *)dictionary {
        unsigned int width = [[dictionary objectForKey:@"width"] unsignedIntValue];
        unsigned int height = [[dictionary objectForKey:@"height"] unsignedIntValue];
        long orientation = [[dictionary objectForKey:@"orientation"] longValue];
        if (!self.mIsScreenSharing) {
            if (orientation == UIImageOrientationLeft
                || orientation == UIImageOrientationRight
                || orientation == UIImageOrientationLeftMirrored
                || orientation == UIImageOrientationRightMirrored) {
                self.mWidthPixels = height;
                self.mHeightPixels = width;
            } else {
                self.mWidthPixels = width;
                self.mHeightPixels = height;
            }
            if (self.mIsStartScreenShareDelayed) {
                [self startDataConfAsPre];
            }
            return;
        }
        unsigned int yPitch = [[dictionary objectForKey:@"yPitch"] unsignedIntValue];
        unsigned int cbCrPitch = [[dictionary objectForKey:@"yPitch"] unsignedIntValue];
        NSData *yData = [dictionary objectForKey:@"yData"];
        NSData *uvData = [dictionary objectForKey:@"uvData"];
        uint8_t *yBuffer = (unsigned char *)[yData bytes];
        uint8_t *cbCrBuffer = (unsigned char *)[uvData bytes];
    
        TSDK_S_CONF_AS_VIEW_DATA_INFO asViewUpdataData;
        memset(&asViewUpdataData, 0, sizeof(TSDK_S_CONF_AS_VIEW_DATA_INFO));
        asViewUpdataData.y_data = yBuffer;
        asViewUpdataData.cb_cr_data = cbCrBuffer;
        asViewUpdataData.y_data_size = yPitch;
        asViewUpdataData.cb_cr_data_size = cbCrPitch;
        asViewUpdataData.width = width;
        asViewUpdataData.height = height;
        asViewUpdataData.orientation = (TSDK_E_IMAGE_ORIENTATION)orientation;
        tsdk_app_share_update_view_data(_confHandle, &asViewUpdataData);
    }
     
  4. UI調(diào)用tsdk_app_share_start()接口開始共享屏幕。
    代碼示例:
    //oc code
    - (void)startDataShare
    {
        TSDK_RESULT result = tsdk_app_share_start(_confHandle, TSDK_E_CONF_APP_SHARE_DESKTOP);
    }
     
  5. 主講人側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)屏幕共享狀態(tài)變更通知消息TSDK_E_CONF_EVT_AS_STATE_CHANGE,UI刷新屏幕共享狀態(tài)信息。
  6. 共享側(cè)SDK自動(dòng)抓取屏幕數(shù)據(jù),由業(yè)務(wù)服務(wù)器發(fā)送給其他與會(huì)者,其他與會(huì)者側(cè)SDK向UI上報(bào)屏幕數(shù)據(jù)更新通知消息TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE。
    代碼示例:
    //oc code
    case TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE:
    {
        DDLogInfo(@"TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE");
        [self handleScreenShareDataConfhandle:notify.param1];
    }
        break;
     
  7. UI調(diào)用tsdk_app_share_get_screen_data()接口獲取屏幕數(shù)據(jù),刷新共享顯示區(qū)域。
    代碼示例:
    //oc code
    -(void)handleScreenShareDataConfhandle:(TSDK_UINT32 )confHandle
    {
        if (!_isStartScreenSharing) {
            DDLogInfo(@"[Meeting] COMPT_MSG_AS_ON_SCREEN_DATA:current share type is not screen share!");
            return;
        }
    
        if (_currentDataShareTypeId != 0x0002 && _currentDataShareTypeId != 0 && _currentDataShareTypeId != -1) {
            return;
        }
    
        TSDK_S_CONF_AS_SCREEN_DATA screenData;
        memset((void *)(&screenData), 0, sizeof(screenData));
        // 獲取數(shù)據(jù)
        TSDK_RESULT dataRet = tsdk_app_share_get_screen_data(confHandle, &screenData);
    
        if (dataRet != TSDK_SUCCESS)
        {
            DDLogInfo(@"tsdk_app_share_get_screen_data failed:%d",dataRet);
            return;
        }
        DDLogInfo(@"tsdk_app_share_get_screen_data :%d",dataRet);
        char *data = (char *)screenData.data;
        if (data == NULL) {
            return;
        }
        TSDK_UINT32 ssize = *((TSDK_UINT32 *)((char *)data + sizeof(TSDK_UINT16)));
        NSData *imageData = [NSData dataWithBytes:data length:ssize];
        if (imageData == nil)
        {
            DDLogInfo(@"share imageData from data fail!");
            return;
        }
        __weak typeof(self) weakSelf = self;
        dispatch_async(espace_dataconf_datashare_queue, ^{
            [weakSelf receiveSharedData:imageData];
        });
    }
     

 

主講人邀請其他與會(huì)者共享屏幕

圖2 主講人邀請其他與會(huì)者共享屏幕流程

  1. 主講人選擇邀請其他與會(huì)者共享屏幕,UI調(diào)用tsdk_app_share_set_owner()接口設(shè)置其他與會(huì)者為共享權(quán)限擁有者。
    說明: 

    SDK并未對接口tup_conf_as_set_owner的調(diào)用者進(jìn)行與角色限制,但實(shí)際應(yīng)用場景中,UI應(yīng)該僅對主講人才提供“邀請其他與會(huì)者共享”入口;成功調(diào)用該接口后,原來擁有共享權(quán)限的用戶的共享權(quán)限會(huì)自動(dòng)取消,正在進(jìn)行的共享會(huì)停止。

    代碼示例:
    //oc code 
    - (BOOL)inviteDataShareWithNumber:(NSString *)number
    {    
        TSDK_RESULT result = tsdk_app_share_set_owner(_confHandle, (TSDK_CHAR*)[number UTF8String], TSDK_E_CONF_AS_ACTION_ADD);        
        return result;
    }
     
  2. 主講人側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)共享權(quán)限擁有者變更通知消息TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新屏幕共享者信息。
    說明: 

    TSDK_E_CONF_EVT_AS_OWNER_CHANGE通知中攜帶的共享類型為TSDK_E_CONF_AS_ACTION_REQUEST,并且共享者ID為自己,UI應(yīng)提示用戶收到共享邀請,并提供“同意共享”和“拒絕共享”入口,“同意共享”則調(diào)起系統(tǒng)屏幕錄制界面,并選擇當(dāng)前程序然后點(diǎn)擊開始共享,“拒絕共享”則調(diào)用tsdk_app_share_set_owner()接口,釋放owner

    代碼示例:
    //oc code
    case TSDK_E_CONF_EVT_AS_OWNER_CHANGE:
    {
        TSDK_E_CONF_AS_ACTION_TYPE actionType = (TSDK_E_CONF_AS_ACTION_TYPE)notify.param2;
        TSDK_S_ATTENDEE *owner =  (TSDK_S_ATTENDEE *)notify.data;
        TSDK_BOOL isSelf = owner->status_info.is_self;
        if (isSelf) {
            if (actionType == TSDK_E_CONF_AS_ACTION_ADD) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:APP_START_SYSTEM_SHARE_VIEW object:nil];
                });
            }else if (actionType == TSDK_E_CONF_AS_ACTION_DELETE){
                self.mIsScreenSharing = NO;
                [self confStopReplay];
                [self respondsECConferenceDelegateWithType:SELF_DATACONF_AS_SCREEN_SHARE_STOP result:nil];
            }else if (actionType == TSDK_E_CONF_AS_ACTION_REQUEST){
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:CONF_SHARE_REQUEST_ACTION
                                                                        object:nil];
    
                });
            }
        }
    }
        break;
    
    - (BOOL)cancelDataShareWithNumber:(NSString *)number
    {
        TSDK_RESULT result = tsdk_app_share_set_owner(_confHandle, (TSDK_CHAR*)[number UTF8String], TSDK_E_CONF_AS_ACTION_DELETE);
    
        return result;
    }
     
    說明: 

    后繼步驟與“主講人共享屏幕”相同。

共享者主動(dòng)結(jié)束共享

圖3 共享者主動(dòng)結(jié)束共享流程 
  1. UI調(diào)用tsdk_app_share_stop()接口停止共享,同時(shí)調(diào)用系統(tǒng)關(guān)閉屏幕錄制方法。
    代碼示例:
    //oc code
    - (void)confStopReplayKitBroadcast
    {
        if (self.mIsScreenSharing) {
            TSDK_RESULT result = tsdk_app_share_stop(_confHandle);
        }
        [self confStopReplay];
    }
    - (void)confStopReplay
    {
        NSError *error = [[NSError alloc] initWithDomain:@"ScreenShare" code:-1 userInfo:@{NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"stop_screen_share", nil)}];
        [self.screenShareManager passMessageObject:@{@"result" : error} identifier:@"StopBroadcast"];
        _mWidthPixels = 0;
        _mHeightPixels = 0;
        self.mIsScreenSharing = NO;
        _mIsStartScreenShareDelayed = NO;
    }
     
  2. 共享側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)屏幕共享狀態(tài)變更通知消息TSDK_E_CONF_EVT_AS_STATE_CHANGE,UI刷新屏幕共享狀態(tài)信息。
  3. 共享側(cè)向UI調(diào)用tsdk_app_share_set_owner()釋放共享權(quán)限擁有者權(quán)限。
  4. 共享側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)共享權(quán)限擁有者變更通知消息TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新屏幕共享者信息。

 

主講人結(jié)束共享者共享

圖4 主講人結(jié)束共享者共享流程 

 

  1. 主講人UI調(diào)用tsdk_app_share_set_owner()接口釋放當(dāng)前共享者共享權(quán)限。
  2. 共享側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)共享權(quán)限擁有者變更通知消息TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新屏幕共享者信息。
    說明: 

    TSDK_E_CONF_EVT_AS_OWNER_CHANGE通知中攜帶的共享類型為TSDK_E_CONF_AS_ACTION_DELETE

    ,并且共享者ID為自己,則表示自己的共享權(quán)限被取消,停止自己共享

    代碼示例:
    //oc code
    case TSDK_E_CONF_EVT_AS_OWNER_CHANGE:
    {
        TSDK_E_CONF_AS_ACTION_TYPE actionType = (TSDK_E_CONF_AS_ACTION_TYPE)notify.param2;
        TSDK_S_ATTENDEE *owner =  (TSDK_S_ATTENDEE *)notify.data;
        TSDK_BOOL isSelf = owner->status_info.is_self;
        if (isSelf) {
            if (actionType == TSDK_E_CONF_AS_ACTION_ADD) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:APP_START_SYSTEM_SHARE_VIEW object:nil];
                });
            }else if (actionType == TSDK_E_CONF_AS_ACTION_DELETE){
                self.mIsScreenSharing = NO;
                [self confStopReplay];
                [self respondsECConferenceDelegateWithType:SELF_DATACONF_AS_SCREEN_SHARE_STOP result:nil];
            }else if (actionType == TSDK_E_CONF_AS_ACTION_REQUEST){
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:CONF_SHARE_REQUEST_ACTION
                                                                        object:nil];
    
                });
            }
        }
    }
        break;
     
  3. 共享側(cè)調(diào)UI用tsdk_app_share_stop()接口停止共享。
    說明: 

    1、調(diào)用tsdk_app_share_stop接口前,先結(jié)束本地系統(tǒng)界面錄制。

    代碼示例:
    //oc code
    - (void)confStopReplayKitBroadcast
    {
        if (self.mIsScreenSharing) {
            TSDK_RESULT result = tsdk_app_share_stop(_confHandle);
        }
        [self confStopReplay];
    }
    - (void)confStopReplay
    {
        NSError *error = [[NSError alloc] initWithDomain:@"ScreenShare" code:-1 userInfo:@{NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"stop_screen_share", nil)}];
        [self.screenShareManager passMessageObject:@{@"result" : error} identifier:@"StopBroadcast"];
    
        _mWidthPixels = 0;
        _mHeightPixels = 0;
        self.mIsScreenSharing = NO;
        _mIsStartScreenShareDelayed = NO;
    }
     
  4. 共享側(cè)和其他與會(huì)者側(cè)SDK向UI上報(bào)屏幕共享狀態(tài)變更通知消息TSDK_E_CONF_EVT_AS_STATE_CHANGE,UI刷新屏幕共享狀態(tài)信息。

注意事項(xiàng)

無。

創(chuàng)建標(biāo)注

描述

在其他終端中,與會(huì)者間可以通過標(biāo)注功能在共享界面進(jìn)行遠(yuǎn)程交流。

  1. 加入數(shù)據(jù)會(huì)議成功。
  2. 加載相關(guān)模塊成功。
說明: 

1、在屏幕共享時(shí),當(dāng)別人發(fā)起標(biāo)注,移動(dòng)端iOS支持進(jìn)行標(biāo)注,不支持主動(dòng)發(fā)起標(biāo)注功能。

業(yè)務(wù)流程

設(shè)置畫筆和畫刷

圖5 設(shè)置畫筆和畫刷流程 
說明: 
  1. 啟用標(biāo)注功能后,可以設(shè)置畫筆和畫刷的屬性,畫筆屬性會(huì)影響標(biāo)注線條的顏色、寬度和類型;畫刷屬性會(huì)影響填充的顏色等;
  2. 設(shè)置畫筆和畫刷后,所有新創(chuàng)建的TSDK_E_ANNOTATION_DRAWING類型標(biāo)注都會(huì)使用新的畫筆和畫刷,舊的標(biāo)注不受影響。
  3. 當(dāng)收到TSDK_E_CONF_EVT_AS_STATE_CHANGE消息中的共享子狀態(tài)sub_state為512時(shí),方可進(jìn)行下面設(shè)置畫筆畫刷操作,然后才可以進(jìn)行標(biāo)注。
//oc code 
case TSDK_E_CONF_EVT_AS_STATE_CHANGE:
{
    DDLogInfo(@"TSDK_E_CONF_EVT_AS_STATE_CHANGE");
    TSDK_S_CONF_AS_STATE_INFO *shareState = (TSDK_S_CONF_AS_STATE_INFO *)notify.data;
    BOOL isStopSharing = NO;
    TSDK_E_CONF_SHARE_STATE state =  shareState->state;
    switch (state) {
        case TSDK_E_CONF_AS_STATE_NULL:
        {
            _isStartScreenSharing = NO;
            isStopSharing = YES;
        }
            break;
        case TSDK_E_CONF_AS_STATE_START:
        case TSDK_E_CONF_AS_STATE_VIEW:
        {
            TSDK_S_CONF_AS_STATE_INFO *as_state_info = (TSDK_S_CONF_AS_STATE_INFO *)notify.data;
            TSDK_UINT32 Annotation = as_state_info->sub_state;

            [self beginAnnotation:(Annotation == 512)];

            _isStartScreenSharing = YES;
            _currentDataShareTypeId = TSDK_E_COMPONENT_AS;
            [self handleScreenShareDataConfhandle:notify.param1];
        }
            break;
        default:
            break;
    }
    if (isStopSharing) {
        __weak typeof(self) weakSelf = self;
        dispatch_async(espace_dataconf_datashare_queue, ^{
            [weakSelf stopSharedData];
            _isStartScreenSharing = NO;
        });
    }
}
    break;
 
  1. UI調(diào)用tsdk_annotation_set_pen()接口設(shè)置畫筆屬性,設(shè)置時(shí)指定當(dāng)前共享的組件ID、畫筆類型和畫筆屬性。
    說明: 
    1. 因僅屏幕共享、文檔共享和白板共享支持標(biāo)注功能,所以組件ID僅支持對應(yīng)的組件ID;
    2. 此接口可以返回原畫筆的屬性,在應(yīng)用層需要記錄原畫筆屬性時(shí),此接口的最后一個(gè)參數(shù)應(yīng)非空。
    代碼示例:
    //oc code 
    - (void)annotationSetPenAndAnnotationColor:(unsigned int)color lineWidth:(int)lineWidth {
    
        TSDK_S_ANNOTATION_PEN_INFO newPenInfo;
        memset(&newPenInfo, 0, sizeof(TSDK_S_ANNOTATION_PEN_INFO));
        newPenInfo.style = TSDK_E_ANNOTATION_PEN_STYLE_SOLID;
        newPenInfo.color = color;
        newPenInfo.width = lineWidth;
    
        TSDK_S_ANNOTATION_PEN_INFO oldPenInfo;
        memset(&oldPenInfo, 0, sizeof(TSDK_S_ANNOTATION_PEN_INFO));
    
    
        TSDK_RESULT result = tsdk_annotation_set_pen(_confHandle, (TSDK_E_COMPONENT_ID)_currentDataShareTypeId, TSDK_E_ANNOTATION_PEN_NORMAL, &newPenInfo, &oldPenInfo);
        DDLogInfo(@"Annotation tsdk_annotation_set_pen: %d", result);
    
    
        TSDK_S_ANNOTATION_BRUSH_INFO newBrushInfo;
        memset(&newBrushInfo, 0, sizeof(TSDK_S_ANNOTATION_BRUSH_INFO));
        newBrushInfo.style = TSDK_E_ANNOTATION_BRUSH_SOLID;
        newBrushInfo.color = color;
    
        TSDK_S_ANNOTATION_BRUSH_INFO oldBrushInfo;
        memset(&oldBrushInfo, 0, sizeof(TSDK_S_ANNOTATION_BRUSH_INFO));
    
        TSDK_RESULT brushResult = tsdk_annotation_set_brush(_confHandle, (TSDK_E_COMPONENT_ID)_currentDataShareTypeId, &newBrushInfo, &oldBrushInfo);
        DDLogInfo(@"Annotation tsdk_annotation_set_brush: %d", brushResult);
    
    }
    
     
  2. UI調(diào)用tsdk_annotation_set_brush()接口設(shè)置畫刷屬性,設(shè)置時(shí)指定當(dāng)前共享的組件ID,畫刷屬性。
    說明: 
    1. 當(dāng)前僅屏幕共享支持標(biāo)注功能,所以組件ID僅支持對應(yīng)的組件ID;
    2. 此接口可以返回原畫刷的屬性,在應(yīng)用層需要記錄原畫刷屬性時(shí),此接口的最后一個(gè)參數(shù)應(yīng)非空。

 

創(chuàng)建幾何標(biāo)注

圖6 創(chuàng)建幾何標(biāo)注流程 
  1. UI調(diào)用tsdk_annotation_create_start()接口開始創(chuàng)建標(biāo)注,標(biāo)注類型為TSDK_E_ANNOTATION_DRAWING。
    說明: 
    1. 屏幕共享過程中、僅具備標(biāo)注權(quán)限的與會(huì)者可以進(jìn)行標(biāo)注操作。應(yīng)用程序界面應(yīng)該根據(jù)當(dāng)前共享狀態(tài)和權(quán)限給用戶提供標(biāo)注入口;
    2. 創(chuàng)建標(biāo)注的接口中用到的坐標(biāo)都是相對于頁面左上角的TWIPS單位坐標(biāo),向右向下為正。
    代碼示例:
    //oc code 
    -(void)conferenceCreateAnnotationWithStartPointx:(long)pointx Pointy:(long)pointy {
        CGFloat hScale = [self heightScale];
        CGFloat wScale = [self widthScale];
    
        TSDK_S_POINT tsdkPoint;
        memset(&tsdkPoint, 0, sizeof(TSDK_S_POINT));
        tsdkPoint.x = (TSDK_INT32)pointx * wScale;
        tsdkPoint.y = (TSDK_INT32)pointy * hScale;
    
        tsdk_annotation_create_start(_confHandle, (TSDK_E_COMPONENT_ID)_currentDataShareTypeId, TSDK_NULL_PTR, TSDK_E_ANNOTATION_DRAWING, 1, &tsdkPoint);
    }
    
     
  2. UI定時(shí)循環(huán)調(diào)用tsdk_annotation_create_update()接口在創(chuàng)建過程中更新數(shù)據(jù)。
    代碼示例:
    //oc code 
    - (void)conferenceUpdateAnnotationWithPointx:(long)pointx Pointy:(long)pointy {
        CGFloat hScale = [self heightScale];
        CGFloat wScale = [self widthScale];
    
        TSDK_S_ANNOTATION_DRAWING_DATA data;
        memset(&data, 0, sizeof(TSDK_S_ANNOTATION_DRAWING_DATA));
        data.point.x = (TSDK_INT32)pointx * wScale;
        data.point.y = (TSDK_INT32)pointy * hScale;
    
        tsdk_annotation_create_update(_confHandle, (TSDK_E_COMPONENT_ID)_currentDataShareTypeId, TSDK_E_ANNOTATION_DRAWING, &data);
    }
    
     
  3. UI調(diào)用tsdk_annotation_create_done()接口完成標(biāo)注創(chuàng)建。
    說明: 

    若完成標(biāo)注創(chuàng)建,則此接口的第三個(gè)參數(shù)應(yīng)設(shè)置為0,否則設(shè)置為1。

    代碼示例:
    //oc code 
    - (void)conferenceFinishAnnotation {
        TSDK_UINT32 annotation_id = 0;
        tsdk_annotation_create_done(_confHandle, (TSDK_E_COMPONENT_ID)_currentDataShareTypeId, 0, &annotation_id);
    }
    
     
  4. 其他與會(huì)者側(cè)SDK向UI上報(bào)數(shù)據(jù)更新消息,屏幕共享時(shí)上報(bào)TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE,文檔共享時(shí)上報(bào)TSDK_E_CONF_EVT_DS_DOC_DRAW_DATA_NOTIFY,白板共享時(shí)上報(bào)TSDK_E_CONF_EVT_WB_DOC_DRAW_DATA_NOTIFY。
    說明: 

    實(shí)際上,在標(biāo)注創(chuàng)建過程中,每次數(shù)據(jù)更新之后都會(huì)收到相應(yīng)的數(shù)據(jù)更新通知,當(dāng)前因流程圖限制,僅呈現(xiàn)在標(biāo)注創(chuàng)建完成后收到數(shù)據(jù)更新通知消息。

  5. UI調(diào)用tsdk_doc_share_get_surface_bmp()/tsdk_app_share_get_screen_data()接口獲取當(dāng)前頁面圖像數(shù)據(jù),并使用獲取到的數(shù)據(jù)刷新共享顯示頁面。

注意事項(xiàng)

無。

 

刪除標(biāo)注

圖7 刪除標(biāo)注流程 
  1. UI調(diào)用tsdk_annotation_delete_annotation()接口刪除標(biāo)注。
    說明: 

    此接口可以對選中的多個(gè)標(biāo)注同時(shí)開始刪除,應(yīng)用程序也可以實(shí)現(xiàn)對標(biāo)注ID的記錄管理,給用戶提供刪除“自己創(chuàng)建的標(biāo)注”、“其他人創(chuàng)建的標(biāo)注”和“所有標(biāo)注”功能入口。

    擦除可以擦除線,擦除所有兩種擦除場景。

    代碼示例:
    //oc code 
    - (void)conferenceEraseAnnotationsIntersectedBySegmentWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint {
    
        TSDK_S_ANNOTATION_HIT_TEST_LINE_INFO hit_test_line_info;
        memset(&hit_test_line_info, 0, sizeof(TSDK_S_ANNOTATION_HIT_TEST_LINE_INFO));
        hit_test_line_info.doc_page_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
        hit_test_line_info.doc_page_info.document_id = 0;
        hit_test_line_info.doc_page_info.page_count = 0;
        hit_test_line_info.doc_page_info.page_index = 0;
    
        hit_test_line_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
    
        CGFloat hScale = [self heightScale];
        CGFloat wScale = [self widthScale];
        hit_test_line_info.start_point.x = (TSDK_INT32)startPoint.x * wScale;
        hit_test_line_info.start_point.y = (TSDK_INT32)startPoint.y * hScale;
    
        hit_test_line_info.end_point.x = (TSDK_INT32)endPoint.x * wScale;
        hit_test_line_info.end_point.y = (TSDK_INT32)endPoint.y * hScale;
    
        hit_test_line_info.hit_test_mode = TSDK_E_ANNOTATION_HIT_TEST_SOMEONE;
    
        strcpy(hit_test_line_info.user_number, [self.selfJoinNumber UTF8String]);
    
        TSDK_UINT32 *selectedIds = NULL;
    
        TSDK_UINT32 idsCount = 0;
    
        TSDK_RESULT result = tsdk_annotation_hit_test_line(_confHandle, &hit_test_line_info, &selectedIds, &idsCount);
        DDLogInfo(@"tsdk_annotation_hit_test_line: %d", result);
    
        if (selectedIds && idsCount > 0) {
            TSDK_S_ANNOTATION_DELETE_INFO delete_info;
            delete_info.annotation_id_list = selectedIds;
            delete_info.count = idsCount;
            delete_info.doc_page_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
            delete_info.doc_page_info.document_id = 0;
            delete_info.doc_page_info.page_count = 0;
            delete_info.doc_page_info.page_index = 0;
    
            delete_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
    
            result = tsdk_annotation_delete_annotation(_confHandle, &delete_info);
            DDLogInfo(@"Annotation tsdk_annotation_delete_annotation: %d", result);
        }
    }
    
    - (void)conferenceEraseAllAnnotations {
        TSDK_S_RECTANGULAR rect = { .left = 0, .top = 0, .right = (TSDK_INT32)INT_MAX, .bottom = (TSDK_INT32)INT_MAX };
        [self conferenceEraseAnnotationsInRect:rect];
    }
    - (void)conferenceEraseAnnotationsInRect:(TSDK_S_RECTANGULAR)rect {
        TSDK_UINT32 *selectedIds = NULL;
        TSDK_UINT32 idsCount = 0;
        TSDK_S_ANNOTATION_HIT_TEST_RECT_INFO hit_test_rect_info;
        hit_test_rect_info.doc_page_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
        if (_currentDataShareTypeId == TSDK_E_COMPONENT_AS) {
            hit_test_rect_info.doc_page_info.document_id = 0;
            hit_test_rect_info.doc_page_info.page_count = 0;
            hit_test_rect_info.doc_page_info.page_index = 0;
        }
        hit_test_rect_info.hit_test_mode = TSDK_E_ANNOTATION_HIT_TEST_SOMEONE;
        hit_test_rect_info.rectangle_area.bottom = rect.bottom;
        hit_test_rect_info.rectangle_area.left = rect.left;
        hit_test_rect_info.rectangle_area.right = rect.right;
        hit_test_rect_info.rectangle_area.top = rect.top;
        strcpy(hit_test_rect_info.user_number, [self.selfJoinNumber UTF8String]);
    
        hit_test_rect_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
    
        TSDK_RESULT result = tsdk_annotation_hit_test_rect(_confHandle, &hit_test_rect_info, &selectedIds, &idsCount);
    
        DDLogInfo(@"Annotation eraseAnnotationsInRect: tup_conf_annotation_hittest_rect returns: %d", result);
    
        if (selectedIds && idsCount > 0) {
            TSDK_S_ANNOTATION_DELETE_INFO delete_info;
            delete_info.annotation_id_list = selectedIds;
            delete_info.count = idsCount;
            delete_info.doc_page_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
            delete_info.doc_page_info.document_id = 0;
            delete_info.doc_page_info.page_count = 0;
            delete_info.doc_page_info.page_index = 0;
    
            delete_info.component_id = (TSDK_E_COMPONENT_ID)_currentDataShareTypeId;
    
            result = tsdk_annotation_delete_annotation(_confHandle, &delete_info);
            DDLogInfo(@"Annotation eraseAnnotationsInRect: tup_conf_annotation_delete returns: %d", result);
        }
    }
    
     
  2. 其他與會(huì)者側(cè)SDK向UI上報(bào)數(shù)據(jù)更新消息,屏幕共享時(shí)上報(bào)TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE,文檔共享時(shí)上報(bào)TSDK_E_CONF_EVT_DS_DOC_DRAW_DATA_NOTIFY,白板共享時(shí)上報(bào)TSDK_E_CONF_EVT_WB_DOC_DRAW_DATA_NOTIFY。
  3. UI調(diào)用tsdk_doc_share_get_surface_bmp()/tsdk_app_share_get_screen_data()接口獲取當(dāng)前頁面圖像數(shù)據(jù),并使用獲取到的數(shù)據(jù)刷新共享顯示頁面。

注意事項(xiàng)

無。

觀看屏幕和程序共享

描述

會(huì)議中,移動(dòng)與會(huì)者觀看屏幕或程序共享。

前提條件

  1. 加入數(shù)據(jù)會(huì)議成功。
  2. 加載屏幕/程序共享模塊成功。

業(yè)務(wù)流程

一、開始觀看屏幕或程序共享

圖8 開始觀看屏幕或程序共享流程 
  1. 會(huì)議中,主講人設(shè)置共享權(quán)限擁有者,邀請其他與會(huì)者進(jìn)行屏幕或程序共享,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新共享者信息。
  2. 共享者開始共享屏幕或程序,移動(dòng)與會(huì)者側(cè)SDK上報(bào)屏幕共享狀態(tài)變更通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_STATE_CHANGE,UI刷新屏幕共享狀態(tài)信息。
    代碼示例:
    case TSDK_E_CONF_EVT_AS_STATE_CHANGE:        
    {            
        DDLogInfo(@"TSDK_E_CONF_EVT_AS_STATE_CHANGE");            
        TSDK_S_CONF_AS_STATE_INFO *shareState = (TSDK_S_CONF_AS_STATE_INFO *)notify.data;                     TSDK_E_CONF_SHARE_STATE state =  shareState->state;            
        if (state == TSDK_E_CONF_AS_STATE_NULL) 
        {                
            [self respondsECConferenceDelegateWithType:DATACONF_SHARE_SCREEN_DATA_STOP result:nil];            
        }        
    }            
    break;
     
  3. 共享側(cè)SDK自動(dòng)抓取屏幕數(shù)據(jù),由業(yè)務(wù)服務(wù)器發(fā)送給其他與會(huì)者,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)屏幕數(shù)據(jù)更新通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE。
    代碼示例:
    case TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE:        
    {            
        DDLogInfo(@"TSDK_E_CONF_EVT_AS_SCREEN_DATA_UPDATE");            
        [self handleScreenShareDataConfhandle:notify.param1];        
    }            
    break;
     
  4. UI調(diào)用tsdk_app_share_get_screen_data()接口獲取屏幕數(shù)據(jù),刷新共享顯示區(qū)域。
    說明: 

    屏幕共享數(shù)據(jù)通過接口同步返回,轉(zhuǎn)換成圖片格式在UI顯示。

    代碼示例:
    -(void)handleScreenShareDataConfhandle:(TSDK_UINT32 )confHandle
    {    
        TSDK_S_CONF_AS_SCREEN_DATA screenData;    
        memset((void *)(&screenData), 0, sizeof(screenData));    
    // get data info    
        TSDK_RESULT dataRet = tsdk_app_share_get_screen_data(confHandle, &screenData);    
        if (dataRet != TSDK_SUCCESS)    
        {        
            DDLogInfo(@"tsdk_app_share_get_screen_data failed:%d",dataRet);        
            return;    
        }    
        DDLogInfo(@"tsdk_app_share_get_screen_data :%d",dataRet);    
        char *data = (char *)screenData.data;    
        TSDK_UINT32 ssize = *((TSDK_UINT32 *)((char *)data + sizeof(TSDK_UINT16)));    
        NSData *imageData = [NSData dataWithBytes:data length:ssize];    
        UIImage *image = [[UIImage alloc] initWithData:imageData];    
        if (image == nil)    
        {        
            DDLogInfo(@"share image from data fail!");       
            return;    
        }    
        NSDictionary *shareDataInfo = @{                                    
            DATACONF_SHARE_DATA_KEY:image                                    
        };    
        [self respondsECConferenceDelegateWithType:DATA_CONF_AS_ON_SCREEN_DATA result:shareDataInfo];
    }
     

 

二、屏幕或程序共享結(jié)束處理

圖9 屏幕或程序共享結(jié)束處理流程 
說明: 

當(dāng)前圖示為共享者主動(dòng)停止共享,若主講人結(jié)束共享者共享,則對于觀看側(cè),相應(yīng)的消息順序相反。

  1. 共享者停止共享,移動(dòng)與會(huì)者側(cè)SDK通過上報(bào)屏幕共享狀態(tài)變更通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_STATE_CHANGE,UI刷新屏幕共享狀態(tài)信息。
  2. 共享者釋放共享權(quán)限,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,UI刷新屏幕共享狀態(tài)信息。

注意事項(xiàng)

無。

聊天

描述

會(huì)議中,所有人可以收到其他與會(huì)者發(fā)送的聊天消息內(nèi)容。

前提條件是加入數(shù)據(jù)會(huì)議成功。

業(yè)務(wù)流程

圖10 發(fā)送聊天消息 
  1. UI調(diào)用接口tsdk_send_chat_msg_in_conference()接口在會(huì)議中發(fā)送公共即時(shí)消息。
    代碼示例:
    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;
     
  2. 會(huì)議中所有用戶(包括消息發(fā)送者)側(cè)SDK均收到消息通知,向UI上報(bào)TSDK_E_CONF_EVT_RECV_CHAT_MSG事件,UI顯示公共即時(shí)消息。
    代碼示例:
    case TSDK_E_CONF_EVT_RECV_CHAT_MSG:
    {
         /*Notify UI*/
    }
     

注意事項(xiàng)

無。

觀看文檔共享

描述

會(huì)議中,移動(dòng)與會(huì)者觀看文檔共享。

說明: 

移動(dòng)應(yīng)用程序暫不具備共享文檔的能力,文檔的共享者為PC應(yīng)用程序。

前提條件

  1. 加入數(shù)據(jù)會(huì)議成功。
  2. 加載文檔共享模塊成功。

業(yè)務(wù)流程

一、開始觀看文檔共享

圖11 開始觀看文檔共享流程 
  1. 會(huì)議中,主講人設(shè)置共享權(quán)限擁有者,邀請其他與會(huì)者進(jìn)行文檔共享,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新共享者信息。
  2. 共享者開始共享文檔,移動(dòng)與會(huì)者側(cè)SDK上報(bào)同步翻頁預(yù)先通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_DS_DOC_CURRENT_PAGE_IND。
    代碼示例:
    case TSDK_E_CONF_EVT_DS_DOC_CURRENT_PAGE_IND:        
    {           
        TSDK_S_DOC_PAGE_BASE_INFO *pageInfo = (TSDK_S_DOC_PAGE_BASE_INFO *)notify.data;            
        [self handleDsDocCurrentPageInfoWithConfHandle:notify.param1 andPageInfo:pageInfo];                    
    }            
        break;
     
  3. UI分別按順序調(diào)用接口tsdk_doc_share_set_current_page(),tsdk_doc_share_get_syn_document_info(),tsdk_doc_share_set_canvas_size(),設(shè)置顯示區(qū)域大小。

    代碼示例:

    - (void)handleDsDocCurrentPageInfoWithConfHandle:(TSDK_INT32)confHandle andPageInfo:(TSDK_S_DOC_PAGE_BASE_INFO *)pageInfo
    {    
        tsdk_doc_share_set_current_page(confHandle, pageInfo, NO);    
        TSDK_S_DOC_PAGE_DETAIL_INFO detailInfo;    
        memset(&detailInfo, 0, sizeof(TSDK_S_DOC_PAGE_DETAIL_INFO));        
        TSDK_RESULT result = tsdk_doc_share_get_syn_document_info(confHandle, pageInfo->component_id, &detailInfo);        
        if (result == TSDK_SUCCESS && (detailInfo.height > 0 && detailInfo.width > 0)) 
        {        
            TSDK_S_SIZE size;        
            memset(&size, 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO));        
            size.width = detailInfo.width;        
            size.high = detailInfo.height;        
            tsdk_doc_share_set_canvas_size(confHandle, pageInfo->component_id, &size, YES);    
    }}
     
  4. 共享側(cè)SDK自動(dòng)抓取文檔數(shù)據(jù),由業(yè)務(wù)服務(wù)器發(fā)送給其他與會(huì)者,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)文檔界面數(shù)據(jù)更新通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_DS_DOC_DRAW_DATA_NOTIFY。
    代碼示例:
    case TSDK_E_CONF_EVT_DS_DOC_DRAW_DATA_NOTIFY:        
    {            
        [self handleDsDocShareDataConfHandle:notify.param1];        
    }            
        break;
     
  5. UI調(diào)用tsdk_doc_share_get_surface_bmp()接口獲取文檔數(shù)據(jù),刷新共享顯示區(qū)域。
    說明: 

    文檔共享數(shù)據(jù)通過接口同步返回,轉(zhuǎn)換成圖片格式在UI顯示。

    代碼示例:
    - (void)handleDsDocShareDataConfHandle:(TSDK_UINT32)confHandle
    {    
        __weak typeof(self) weakSelf = self;    
        dispatch_async(espace_dataconf_datashare_queue, ^{        
            @autoreleasepool {            
                TSDK_UINT32 iWidth = 0;            
                TSDK_UINT32 iHeight = 0;            
                TSDK_VOID *pData = tsdk_doc_share_get_surface_bmp(confHandle, TSDK_E_COMPONENT_DS, &iWidth, &iHeight);            
                if (NULL == pData) {                
                DDLogInfo(@"[Meeting] Data is null.");                
                return;            
                }           
                char *pBmpData = (char *)pData;            
                TSDK_UINT32 wSize = *(TSDK_UINT32 *)((char *)pBmpData + sizeof(TSDK_UINT16));           
                NSData *imgData = [NSData dataWithBytes:(void*)pBmpData length:wSize];            
                if (nil == imgData) {                
                DDLogInfo(@"[Meeting] Make image from data failed.");                
                return;            
                }            
                [weakSelf receiveSharedData:imgData];        
            }    
        });
    }
     

 

二、文檔共享結(jié)束處理

圖12 文檔共享結(jié)束處理流程 
說明: 

當(dāng)前圖示為共享者主動(dòng)停止共享,若主講人結(jié)束共享者共享,則對于觀看側(cè),相應(yīng)的消息順序相反。

  1. 共享者停止共享,移動(dòng)與會(huì)者側(cè)SDK通過上報(bào)文檔共享結(jié)束通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_DS_DOC_DEL,UI刷新界面結(jié)束共享。
  2. 共享者釋放共享權(quán)限,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,UI刷新共享者信息。

注意事項(xiàng)

無。

觀看白板共享

描述

會(huì)議中,移動(dòng)與會(huì)者觀看白板共享。

說明: 

移動(dòng)應(yīng)用程序暫不具備共享白板的能力,白板的共享者為PC應(yīng)用程序。

前提條件:

  1. 加入數(shù)據(jù)會(huì)議成功。
  2. 加載白板共享模塊成功。

業(yè)務(wù)流程

一、開始觀看白板共享

圖13 開始觀看白板共享流程 
  1. 會(huì)議中,主講人設(shè)置共享權(quán)限擁有者,邀請其他與會(huì)者進(jìn)行文檔白板,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,攜帶當(dāng)前共享權(quán)限擁有者ID,UI刷新共享者信息。
  2. 共享者開始共享白板,移動(dòng)與會(huì)者側(cè)SDK上報(bào)同步翻頁預(yù)先通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE_IND。
    代碼示例:
    case TSDK_E_CONF_EVT_WB_DOC_CURRENT_PAGE_IND:        
    {           
        TSDK_S_DOC_PAGE_BASE_INFO *pageInfo = (TSDK_S_DOC_PAGE_BASE_INFO *)notify.data;            
        [self handleDsDocCurrentPageInfoWithConfHandle:notify.param1 andPageInfo:pageInfo];                    
    }            
        break;
     
  3. UI分別按順序調(diào)用接口tsdk_doc_share_set_current_page(),tsdk_doc_share_get_syn_document_info(),tsdk_doc_share_set_canvas_size(),設(shè)置顯示區(qū)域大小。

    代碼示例:

    - (void)handleDsDocCurrentPageInfoWithConfHandle:(TSDK_INT32)confHandle andPageInfo:(TSDK_S_DOC_PAGE_BASE_INFO *)pageInfo
    {    
        tsdk_doc_share_set_current_page(confHandle, pageInfo, NO);    
        TSDK_S_DOC_PAGE_DETAIL_INFO detailInfo;    
        memset(&detailInfo, 0, sizeof(TSDK_S_DOC_PAGE_DETAIL_INFO));        
        TSDK_RESULT result = tsdk_doc_share_get_syn_document_info(confHandle, pageInfo->component_id, &detailInfo);        
        if (result == TSDK_SUCCESS && (detailInfo.height > 0 && detailInfo.width > 0)) 
        {        
            TSDK_S_SIZE size;        
            memset(&size, 0, sizeof(TSDK_S_DOC_PAGE_BASE_INFO));        
            size.width = detailInfo.width;        
            size.high = detailInfo.height;        
            tsdk_doc_share_set_canvas_size(confHandle, pageInfo->component_id, &size, YES);    
    }}
     
  4. 共享側(cè)SDK自動(dòng)抓取白板數(shù)據(jù),由業(yè)務(wù)服務(wù)器發(fā)送給其他與會(huì)者,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)白板界面數(shù)據(jù)更新通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_WB_DOC_DRAW_DATA_NOTIFY。
    代碼示例:
    case TSDK_E_CONF_EVT_WB_DOC_DRAW_DATA_NOTIFY:        
    {            
        [self handleWbDocShareDataConfHandle:notify:notify.param1];        
    }            
        break;
     
  5. UI調(diào)用tsdk_doc_share_get_surface_bmp()接口獲取白板數(shù)據(jù),刷新共享顯示區(qū)域。
    說明: 

    白板共享數(shù)據(jù)通過接口同步返回,轉(zhuǎn)換成圖片格式在UI顯示。

    代碼示例:
    - (void)handleWbDocShareDataConfHandle:(TSDK_UINT32)confHandle
    {    
        __weak typeof(self) weakSelf = self;    
        dispatch_async(espace_dataconf_datashare_queue, ^{        
            @autoreleasepool {            
                TSDK_UINT32 iWidth = 0;            
                TSDK_UINT32 iHeight = 0;            
                TSDK_VOID *pData = tsdk_doc_share_get_surface_bmp(confHandle, TSDK_E_COMPONENT_DS, &iWidth, &iHeight);            
                if (NULL == pData) {                
                DDLogInfo(@"[Meeting] Data is null.");                
                return;            
                }           
                char *pBmpData = (char *)pData;            
                TSDK_UINT32 wSize = *(TSDK_UINT32 *)((char *)pBmpData + sizeof(TSDK_UINT16));           
                NSData *imgData = [NSData dataWithBytes:(void*)pBmpData length:wSize];            
                if (nil == imgData) {                
                DDLogInfo(@"[Meeting] Make image from data failed.");                
                return;            
                }            
                [weakSelf receiveSharedData:imgData];        
            }    
        });
    }
     

 

二、白板共享結(jié)束處理

圖14 白板共享結(jié)束處理流程 
說明: 

當(dāng)前圖示為共享者主動(dòng)停止共享,若主講人結(jié)束共享者共享,則對于觀看側(cè),相應(yīng)的消息順序相反。

  1. 共享者停止共享,移動(dòng)與會(huì)者側(cè)SDK通過上報(bào)白板共享結(jié)束通知消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_WB_DOC_DEL,UI刷新界面結(jié)束共享。
  2. 共享者釋放共享權(quán)限,移動(dòng)與會(huì)者側(cè)SDK向UI上報(bào)共享者變更消息,對應(yīng)的消息ID為TSDK_E_CONF_EVT_AS_OWNER_CHANGE,UI刷新共享者信息。

注意事項(xiàng)

無。