






sudo gem install cocoapods
pod init
platform :ios, '8.0'target 'App' do# RTC Engine 精简版# 安装包体积增量最小,但仅支持 RTC Engine 和 直播播放器(TXLivePlayer)两项功能。pod 'TXLiteAVSDK_TRTC', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_TRTC.podspec'# Professional 专业版# 包含 RTC Engine、直播播放器(TXLivePlayer)、RTMP 推流(TXLivePusher)、点播播放器(TXVodPlayer)和短视频录制和编辑(UGSV)等众多功能。# pod 'TXLiteAVSDK_Professional', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_Professional.podspec'# 美颜 AR SDK 例如:S1-07套餐如下pod 'TencentEffect_S1-07'end
pod install
pod update
pod setuppod repo updaterm ~/Library/Caches/CocoaPods/search_index.json
-ObjC。


[TELicenseCheck setTELicense:LicenseURL key:LicenseKey completion:^(NSInteger authresult, NSString * _Nonnull errorMsg) {if (authresult == TELicenseCheckOk) {NSLog(@"鉴权成功");} else {NSLog(@"鉴权失败");}}];
// 创建 RTC Engine SDK 实例(单例模式)self.trtcCloud = [TRTCCloud sharedInstance];// 设置事件监听器self.trtcCloud.delegate = self;// 来自 SDK 的各类事件通知(比如:错误码,警告码,音视频状态参数等)- (void)onError:(TXLiteAVError)errCode errMsg:(nullable NSString *)errMsg extInfo:(nullable NSDictionary *)extInfo {NSLog(@"%d: %@", errCode, errMsg);}- (void)onWarning:(TXLiteAVWarning)warningCode warningMsg:(nullable NSString *)warningMsg extInfo:(nullable NSDictionary *)extInfo {NSLog(@"%d: %@", warningCode, warningMsg);}// 移除事件监听器self.trtcCloud.delegate = nil;// 销毁 RTC Engine SDK 实例(单例模式)[TRTCCloud destroySharedIntance];
// 加载美颜相关资源NSDictionary *assetsDict = @{@"core_name":@"LightCore.bundle",@"root_path":[[NSBundle mainBundle] bundlePath]};// 初始化腾讯特效 SDKself.beautyKit = [[XMagic alloc] initWithRenderSize:previewSize assetsDict:assetsDict];// 释放腾讯特效 SDK[self.beautyKit deinit]
// 获取用于展示主播本地画面预览的视频渲染控件@property (nonatomic, strong) UIView *anchorPreviewView;@property (nonatomic, strong) TRTCCloud *trtcCloud;- (void)setupTRTC {self.trtcCloud = [TRTCCloud sharedInstance];self.trtcCloud.delegate = self;// 设置视频编码参数,决定远端用户看到的画面质量TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 1300;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera 可指定使用前置/后置摄像头进行视频采集[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.anchorPreviewView];// 这里可指定声音音质,从低到高分别为 SPEECH/DEFAULT/MUSIC[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}
enterRoom 之前调用以上接口,SDK 只会开启摄像头预览和音频采集,并一直等到您调用 enterRoom 之后才开始推流。enterRoom 之后调用以上接口,SDK 会开启摄像头预览和音频采集,并自动开始推流。- (void)setupRenderParams {TRTCRenderParams *params = [[TRTCRenderParams alloc] init];// 画面镜像模式params.mirrorType = TRTCVideoMirrorTypeAuto;// 画面填充模式params.fillMode = TRTCVideoFillMode_Fill;// 画面旋转角度params.rotation = TRTCVideoRotation_0;// 设置本地画面的渲染参数[self.trtcCloud setLocalRenderParams:params];// 设置编码器输出的画面镜像模式[self.trtcCloud setVideoEncoderMirror:YES];// 设置视频编码器输出的画面方向[self.trtcCloud setVideoEncoderRotation:TRTCVideoRotation_0];}
- (void)enterRoomByAnchorWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// 以字符串房间号为例params.strRoomId = roomId;params.userId = userId;// 从业务后台获取到的 UserSigparams.userSig = @"userSig";// 替换成您的 SDKAppIDparams.sdkAppId = 0;// 指定主播角色params.role = TRTCRoleAnchor;// 以互动直播场景进房[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// 进房结果事件回调- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result 代表加入房间所消耗的时间(毫秒)NSLog(@"Enter room succeed!");} else {// result 代表进房失败的错误码NSLog(@"Enter room failed!");}}
roomId 和字符串类型 strRoomId,两种类型的房间不互通,建议统一房间号类型。TRTCAppSceneLIVE。- (void)enterRoomByAudienceWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// 以字符串房间号为例params.strRoomId = roomId;params.userId = userId;// 从业务后台获取到的 UserSigparams.userSig = @"userSig";// 替换成您的 SDKAppIDparams.sdkAppId = 0;// 指定观众角色params.role = TRTCRoleAudience;// 以互动直播场景进房[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// 进房结果事件回调- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result 代表加入房间所消耗的时间(毫秒)NSLog(@"Enter room succeed!");} else {// result 代表进房失败的错误码NSLog(@"Enter room failed!");}}
- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {// 某远端用户发布/取消了自己的音频// 在自动订阅模式下,您无需做任何操作,SDK 会自动播放远端用户音频}- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// 某远端用户发布/取消了主路视频画面if (available) {// 订阅远端用户的视频流,并绑定视频渲染控件[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteView];} else {// 停止订阅远端用户的视频流,并释放渲染控件[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
- (void)setupRemoteRenderParams {TRTCRenderParams *params = [[TRTCRenderParams alloc] init];// 画面镜像模式params.mirrorType = TRTCVideoMirrorTypeAuto;// 画面填充模式params.fillMode = TRTCVideoFillMode_Fill;// 画面旋转角度params.rotation = TRTCVideoRotation_0;// 设置远端画面的渲染模式[self.trtcCloud setRemoteRenderParams:@"userId" streamType:TRTCVideoStreamTypeBig params:params];}
- (void)switchToAnchor {// 切换为主播角色[self.trtcCloud switchRole:TRTCRoleAnchor];}// 切换角色事件回调- (void)onSwitchRole:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {if (errCode == ERR_NULL) {// 切换角色成功}}
- (void)setupTRTC {// 设置视频编码参数,决定远端用户看到的画面质量TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_480_270;encParam.videoFps = 15;encParam.videoBitrate = 550;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera 可指定使用前置/后置摄像头进行视频采集[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.audiencePreviewView];// 这里可指定声音音质,从低到高分别为 SPEECH/DEFAULT/MUSIC[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}
- (void)switchToAudience {// 切换为观众角色[self.trtcCloud switchRole:TRTCRoleAudience];}// 切换角色事件回调- (void)onSwitchRole:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {if (errCode == ERR_NULL) {// 停止摄像头采集推流[self.trtcCloud stopLocalPreview];// 停止麦克风采集推流[self.trtcCloud stopLocalAudio];}}
- (void)exitRoom {[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}// 离开房间事件回调- (void)onExitRoom:(NSInteger)reason {if (reason == 0) {NSLog(@"主动调用 exitRoom 退出房间");} else if (reason == 1) {NSLog(@"被服务器踢出当前房间");} else if (reason == 2) {NSLog(@"当前房间整个被解散");}}
onExitRoom 回调通知到您。enterRoom 或者切换到其他的音视频 SDK,请等待 onExitRoom 回调到来后再执行相关操作。否则可能会遇到例如摄像头、麦克风设备被强占等各种异常问题。DismissRoom(区分数字房间 ID 和字符串房间 ID),您可以调用此接口把房间所有用户从房间移出,并解散房间。exitRoom 接口,将房间内的所有主播和听众完成退房,退房后,根据 RTC Engine 房间生命周期规则,房间将会自动解散,详情请参见 退出房间。- (void)connectOtherRoom:(NSString *)roomId {NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];// 数字房间号为 roomId[jsonDict setObject:roomId forKey:@"strRoomId"];[jsonDict setObject:self.userId forKey:@"userId"];NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:NSJSONWritingPrettyPrinted error:nil];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];[self.trtcCloud connectOtherRoom:jsonString];}// 请求跨房连麦的结果回调- (void)onConnectOtherRoom:(NSString *)userId errCode:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {// 要跨房通话的另一个房间中的主播的用户 ID// 错误码,ERR_NULL 代表请求成功// 错误信息}
- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {// 某远端用户发布/取消了自己的音频// 在自动订阅模式下,您无需做任何操作,SDK 会自动播放远端用户音频}- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// 某远端用户发布/取消了主路视频画面if (available) {// 订阅远端用户的视频流,并绑定视频渲染控件[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteView];} else {// 停止订阅远端用户的视频流,并释放渲染控件[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
// 退出跨房连麦[self.trtcCloud disconnectOtherRoom];// 退出跨房连麦的结果回调- (void)onDisconnectOtherRoom:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {}
DisconnectOtherRoom() 后,即退出与所有其他房间主播的跨房 PK 连麦。DisconnectOtherRoom() 退出跨房 PK 连麦。NSString *beautyConfigPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];beautyConfigPath = [beautyConfigPath stringByAppendingPathComponent:@"beauty_config.json"];NSFileManager *localFileManager=[[NSFileManager alloc] init];BOOL isDir = YES;NSDictionary * beautyConfigJson = @{};if ([localFileManager fileExistsAtPath:beautyConfigPath isDirectory:&isDir] && !isDir) {NSString *beautyConfigJsonStr = [NSString stringWithContentsOfFile:beautyConfigPath encoding:NSUTF8StringEncoding error:nil];NSError *jsonError;NSData *objectData = [beautyConfigJsonStr dataUsingEncoding:NSUTF8StringEncoding];beautyConfigJson = [NSJSONSerialization JSONObjectWithData:objectDataoptions:NSJSONReadingMutableContainerserror:&jsonError];}NSDictionary *assetsDict = @{@"core_name":@"LightCore.bundle",@"root_path":[[NSBundle mainBundle] bundlePath],@"tnn_"@"beauty_config":beautyConfigJson};// 初始化SDK:width和height分别是texture的宽高self.xMagicKit = [[XMagic alloc] initWithRenderSize:CGSizeMake(width,height) assetsDict:assetsDict];
// RTC Engine SDK 设置第三方美颜的视频数据回调[self.trtcCloud setLocalVideoProcessDelegete:self pixelFormat:TRTCVideoPixelFormat_Texture_2D bufferType:TRTCVideoBufferType_Texture];#pragma mark - TRTCVideoFrameDelegate// 构造 YTProcessInput 传入到 SDK 内做渲染处理- (uint32_t)onProcessVideoFrame:(TRTCVideoFrame *_Nonnull)srcFrame dstFrame:(TRTCVideoFrame *_Nonnull)dstFrame {if (!self.xMagicKit) {[self buildBeautySDK:srcFrame.width and:srcFrame.height texture:srcFrame.textureId];//初始化XMagic SDKself.heightF = srcFrame.height;self.widthF = srcFrame.width;}if(self.xMagicKit!=nil && (self.heightF!=srcFrame.height || self.widthF!=srcFrame.width)){self.heightF = srcFrame.height;self.widthF = srcFrame.width;[self.xMagicKit setRenderSize:CGSizeMake(srcFrame.width, srcFrame.height)];}YTProcessInput *input = [[YTProcessInput alloc] init];input.textureData = [[YTTextureData alloc] init];input.textureData.texture = srcFrame.textureId;input.textureData.textureWidth = srcFrame.width;input.textureData.textureHeight = srcFrame.height;input.dataType = kYTTextureData;YTProcessOutput *output = [self.xMagicKit process:input withOrigin:YtLightImageOriginTopLeft withOrientation:YtLightCameraRotation0];dstFrame.textureId = output.textureData.texture;return 0;}
- (void)enableDualStreamMode:(BOOL)enable {// 小流的视频编码参数(可自定义)TRTCVideoEncParam *smallVideoEncParam = [[TRTCVideoEncParam alloc] init];smallVideoEncParam.videoResolution = TRTCVideoResolution_480_270;smallVideoEncParam.videoFps = 15;smallVideoEncParam.videoBitrate = 550;smallVideoEncParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud enableEncSmallVideoStream:enable withQuality:smallVideoEncParam];}
// 订阅远端用户视频流时可选视频流类型[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:view];// 亦可随时切换指定远端用户的大小画面[self.trtcCloud setRemoteVideoStreamType:userId type:TRTCVideoStreamTypeSmall];
streamType 视频流类型为 TRTCVideoStreamTypeSmall 来拉取低清小画面观看。// 更新本地预览画面渲染控件[self.trtcCloud updateLocalView:view];// 更新远端用户视频渲染控件[self.trtcCloud updateRemoteView:view streamType:TRTCVideoStreamTypeBig forUser:userId];
view 为目标视频渲染控件,streamType 仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub。// 构造点赞消息体NSDictionary *msgDict = @{@"type": @1, // 点赞类型@"likeCount": @10 // 点赞数量};NSDictionary *dataDict = @{@"cmd": @"like_msg",@"msg": msgDict};NSError *error;NSData *data = [NSJSONSerialization dataWithJSONObject:dataDict options:0 error:&error];// 发送群自定义消息(点赞消息建议设置为低优先级)[[V2TIMManager sharedInstance] sendGroupCustomMessage:data to:groupID priority:V2TIM_PRIORITY_LOW succ:^{// 发送点赞消息成功// 本地渲染点赞效果} fail:^(int code, NSString *desc) {// 发送点赞消息失败}];
// 收到群自定义消息[[V2TIMManager sharedInstance] addSimpleMsgListener:self];- (void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data {if (data.length > 0) {NSError *error;NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];if (!error) {NSString *command = dataDict[@"cmd"];NSDictionary *msgDict = dataDict[@"msg"];if ([command isEqualToString:@"like_msg"]) {NSNumber *type = msgDict[@"type"]; // 点赞类型NSNumber *likeCount = msgDict[@"likeCount"]; // 点赞数量// 根据点赞类型和数量渲染点赞效果}} else {NSLog(@"解析错误: %@", error.localizedDescription);}}}
https://xxxxxx/v4/group_open_http_svc/send_group_msg?sdkappid=88888888&identifier=admin&usersig=xxx&random=99999999&contenttype=json
{"GroupId": "@TGS#12DEVUDHQ","Random": 2784275388,"MsgPriority": "High", // 消息的优先级,礼物消息应设置为高优先级"MsgBody": [{"MsgType": "TIMCustomElem","MsgContent": {// type: 礼物类型; giftUrl: 礼物资源地址; giftName: 礼物名称; giftCount: 礼物数量"Data": "{\\"cmd\\": \\"gift_msg\\", \\"msg\\": {\\"type\\": 1, \\"giftUrl\\": \\"xxx\\", \\"giftName\\": \\"xxx\\", \\"giftCount\\": 1}}"}}]}
// 收到群自定义消息[[V2TIMManager sharedInstance] addSimpleMsgListener:self];- (void)onRecvGroupCustomMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info customData:(NSData *)data {if (data.length > 0) {NSError *error;NSDictionary *dataDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];if (!error) {NSString *command = dataDict[@"cmd"];NSDictionary *msgDict = dataDict[@"msg"];if ([command isEqualToString:@"gift_msg"]) {NSNumber *type = msgDict[@"type"]; // 礼物类型NSNumber *giftCount = msgDict[@"giftCount"]; // 礼物数量NSString *giftUrl = msgDict[@"giftUrl"]; // 礼物资源地址NSString *giftName = msgDict[@"giftName"]; // 礼物名称// 根据礼物类型、礼物数量、礼物资源地址、礼物名称渲染礼物特效}} else {NSLog(@"解析错误: %@", error.localizedDescription);}}}
// 发送公屏弹幕消息[[V2TIMManager sharedInstance] sendGroupTextMessage:text to:groupID priority:V2TIM_PRIORITY_NORMAL succ:^{// 发送弹幕消息成功// 本地展示消息文本} fail:^(int code, NSString *desc) {// 发送弹幕消息失败}];// 接收公屏弹幕消息[[V2TIMManager sharedInstance] addSimpleMsgListener:self];- (void)onRecvGroupTextMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info text:(NSString *)text {// 根据发送者信息 info 和消息文本 text 渲染弹幕消息}
枚举 | 取值 | 描述 |
ERR_TRTC_INVALID_USER_SIG | -3320 | 进房参数 userSig 不正确,请检查 TRTCParams.userSig 是否为空。 |
ERR_TRTC_USER_SIG_CHECK_FAILED | -100018 | UserSig 校验失败,请检查参数 TRTCParams.userSig 是否填写正确或已经过期。 |
枚举 | 取值 | 描述 |
ERR_TRTC_CONNECT_SERVER_TIMEOUT | -3308 | 请求进房超时,请检查是否断网或者是否开启 VPN,您也可以切换4G进行测试。 |
ERR_TRTC_INVALID_SDK_APPID | -3317 | 进房参数 sdkAppId 错误,请检查 TRTCParams.sdkAppId 是否为空 |
ERR_TRTC_INVALID_ROOM_ID | -3318 | 进房参数 roomId 错误,请检查 TRTCParams.roomId 或 TRTCParams.strRoomId 是否为空,注意 roomId 和 strRoomId 不可混用。 |
ERR_TRTC_INVALID_USER_ID | -3319 | 进房参数 userId 不正确,请检查 TRTCParams.userId 是否为空。 |
ERR_TRTC_ENTER_ROOM_REFUSED | -3340 | 进房请求被拒绝,请检查是否连续调用 enterRoom 进入相同 Id 的房间。 |
枚举 | 取值 | 描述 |
ERR_CAMERA_START_FAIL | -1301 | 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序。 |
ERR_MIC_START_FAIL | -1302 | 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序。 |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了。 |
ERR_MIC_NOT_AUTHORIZED | -1317 | 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了。 |
ERR_CAMERA_OCCUPY | -1316 | 摄像头正在被占用中,可尝试打开其他摄像头。 |
ERR_MIC_OCCUPY | -1319 | 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败。 |
setLocalRenderParams 和视频编码镜像 setVideoEncoderMirror,两者分别影响本地预览画面镜像效果,以及视频编码输出画面的镜像效果(远端观众及云端录制的镜像模式)。如果希望本地预览的镜像效果同时在远端观众侧生效,请按照如下方法进行编码。// 设置本地画面的渲染参数TRTCRenderParams *params = [[TRTCRenderParams alloc] init];params.mirrorType = TRTCVideoMirrorTypeEnable; // 画面镜像模式params.fillMode = TRTCVideoFillMode_Fill; // 画面填充模式params.rotation = TRTCVideoRotation_0; // 画面旋转角度[self.trtcCloud setLocalRenderParams:params];// 设置编码器输出的画面镜像模式[self.trtcCloud setVideoEncoderMirror:YES];
// 获取摄像头的最大缩放倍数(仅适用于移动端)CGFloat zoomRatio = [[self.trtcCloud getDeviceManager] getCameraZoomMaxRatio];// 设置摄像头的缩放倍数(仅适用于移动端)// 取值范围1-5,取值为1表示最远视角(正常镜头),取值为5表示最近视角(放大镜头);最大值推荐为5,若超过5,视频数据会变得模糊不清[[self.trtcCloud getDeviceManager] setCameraZoomRatio:zoomRatio];
// 开启或关闭摄像头的自动对焦功能(仅适用于移动端)[[self.trtcCloud getDeviceManager] enableCameraAutoFocus:NO];// 设置摄像头的对焦位置(仅适用于移动端)// 使用该接口的前提是先通过 enableCameraAutoFocus 关闭自动对焦功能[[self.trtcCloud getDeviceManager] setCameraFocusPosition:CGPointMake(x, y)];
// 判断当前是否为前置摄像头(仅适用于移动端)BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];// 切换前置或后置摄像头(仅适用于移动端)// 传入true: 切换为前置;传入false: 切换为后置[[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];
文档反馈