App Name
, Package Name
and Bundle ID
. Choose Tencent Effect, and choose the capabilities to be tested: Advanced Package S1-07, Atomic Capability X1-01, Atomic Capability X1-02, and Atomic Capability X1-03. After you check it, accurately fill in the company name, and industry type. Upload company service license, click OK to submit the review application, and wait for the manual review process.sudo gem install cocoapods
pod init
platform :ios, '8.0'target 'App' do# TRTC Lite Edition# The installation package has the minimum incremental size. But it only supports two features of Real-Time Communication (TRTC) and TXLivePlayer for live streaming playback.pod 'TXLiteAVSDK_TRTC', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_TRTC.podspec'# Pro Edition# Includes a wide range of features such as Real-Time Communication (TRTC), TXLivePlayer for live streaming playback, TXLivePusher for RTMP push streams, TXVodPlayer for on-demand playback, and UGSV for short video recording and editing.# pod 'TXLiteAVSDK_Professional', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_Professional.podspec'# Tencent Effect SDK example of S1-07 package is as follows: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(@"Authentication successful.");} else {NSLog(@"Authentication failed.");}}];
// Create TRTC SDK instance (Single Instance Pattern).self.trtcCloud = [TRTCCloud sharedInstance];// Set event listeners.self.trtcCloud.delegate = self;// Notifications from various SDK events (e.g., error codes, warning codes, audio and video status parameters, etc.).- (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);}// Remove event listener.self.trtcCloud.delegate = nil;// Terminate TRTC SDK instance (Singleton Pattern).[TRTCCloud destroySharedIntance];
// Load beauty-related resources.NSDictionary *assetsDict = @{@"core_name":@"LightCore.bundle",@"root_path":[[NSBundle mainBundle] bundlePath]};// Initialize the Tencent Effect SDK.self.beautyKit = [[XMagic alloc] initWithRenderSize:previewSize assetsDict:assetsDict];// Release the Tencent Effect SDK.[self.beautyKit deinit]
// Obtain the video rendering control for displaying the anchor's local video preview.@property (nonatomic, strong) UIView *anchorPreviewView;@property (nonatomic, strong) TRTCCloud *trtcCloud;- (void)setupTRTC {self.trtcCloud = [TRTCCloud sharedInstance];self.trtcCloud.delegate = self;// Set video encoding parameters to determine the picture quality seen by remote users.TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 1300;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera can specify using the front/rear camera for video capture.[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.anchorPreviewView];// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSIC.[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}
enterRoom
. The SDK will only start the camera preview and audio capture, and wait until you call enterRoom
to start streaming.enterRoom
. The SDK will start the camera preview and audio capture and automatically start streaming.- (void)setupRenderParams {TRTCRenderParams *params = [[TRTCRenderParams alloc] init];// Video mirror modeparams.mirrorType = TRTCVideoMirrorTypeAuto;// Video fill modeparams.fillMode = TRTCVideoFillMode_Fill;// Video rotation angleparams.rotation = TRTCVideoRotation_0;// Set the rendering parameters for the local video.[self.trtcCloud setLocalRenderParams:params];// Set the video mirror mode for the encoder output.[self.trtcCloud setVideoEncoderMirror:YES];// Set the rotation of the video encoder output.[self.trtcCloud setVideoEncoderRotation:TRTCVideoRotation_0];}
- (void)enterRoomByAnchorWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// Take the room ID string as an example.params.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backend.params.userSig = @"userSig";// Replace with your SDKAppID.params.sdkAppId = 0;// Specify the anchor role.params.role = TRTCRoleAnchor;// Enter the room in an interactive live streaming scenario.[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// Event callback for the result of entering the room.- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result indicates the time taken (in milliseconds) to join the room.NSLog(@"Enter room succeed!");} else {// result indicates the error code when you fail to enter the room.NSLog(@"Enter room failed!");}}
roomId
and string type strRoomId
. The rooms of these two types are not interconnected. It is recommended to unify the room ID type.TRTCAppSceneLIVE
as the room entry mode.- (void)enterRoomByAudienceWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// Take the room ID string as an example.params.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backend.params.userSig = @"userSig";// Replace with your SDKAppID.params.sdkAppId = 0;// Specify the audience role.params.role = TRTCRoleAudience;// Enter the room in an interactive live streaming scenario.[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// Event callback for the result of entering the room.- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result indicates the time taken (in milliseconds) to join the room.NSLog(@"Enter room succeed!");} else {// result indicates the error code when you fail to enter the room.NSLog(@"Enter room failed!");}}
- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes their audio.// Under the automatic subscription mode, you do not need to do anything. The SDK will automatically play the remote user's audio.}- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes the primary video.if (available) {// Subscribe to the remote user's video stream and bind the video rendering control.[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteView];} else {// Unsubscribe to the remote user's video stream and release the rendering control.[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
- (void)setupRemoteRenderParams {TRTCRenderParams *params = [[TRTCRenderParams alloc] init];// Video mirror modeparams.mirrorType = TRTCVideoMirrorTypeAuto;// Video fill modeparams.fillMode = TRTCVideoFillMode_Fill;// Video rotation angleparams.rotation = TRTCVideoRotation_0;// Set the rendering mode for the remote video.[self.trtcCloud setRemoteRenderParams:@"userId" streamType:TRTCVideoStreamTypeBig params:params];}
- (void)switchToAnchor {// Switched to the anchor role.[self.trtcCloud switchRole:TRTCRoleAnchor];}// Event callback for switching the role.- (void)onSwitchRole:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {if (errCode == ERR_NULL) {// Role switched successfully.}}
- (void)setupTRTC {// Set video encoding parameters to determine the picture quality seen by remote users.TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_480_270;encParam.videoFps = 15;encParam.videoBitrate = 550;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera can specify using the front/rear camera for video capture.[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.audiencePreviewView];// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSIC.[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}
- (void)switchToAudience {// Switched to the audience role.[self.trtcCloud switchRole:TRTCRoleAudience];}// Event callback for switching the role.- (void)onSwitchRole:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {if (errCode == ERR_NULL) {// Stop camera capture and streaming.[self.trtcCloud stopLocalPreview];// Stop microphone capture and streaming.[self.trtcCloud stopLocalAudio];}}
- (void)exitRoom {[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}// Event callback for exiting the room.- (void)onExitRoom:(NSInteger)reason {if (reason == 0) {NSLog(@"Proactively call exitRoom to exit the room.");} else if (reason == 1) {NSLog(@"Removed from the current room by the server.");} else if (reason == 2) {NSLog(@"The current room is dissolved.");}}
onExitRoom
callback notification to inform you.enterRoom
again or switch to another audio/video SDK, wait for the onExitRoom
callback before proceeding. Otherwise, you may encounter exceptions such as the camera or microphone being forcefully occupied.DismissRoom
(differentiating between numeric room ID and string room ID). You can call this API to remove all users from the room and dissolve the room.exitRoom
API of each client, all the anchors and audiences in the room can be completed of room exit. After room exit, according to TRTC room lifecycle rules, the room will automatically be dissolved. For details, see Exit Room.// Obtain the video rendering control for displaying the anchor's local video preview.@property (nonatomic, strong) UIView *anchorPreviewView;- (void)setupTRTC {self.trtcCloud = [TRTCCloud sharedInstance];self.trtcCloud.delegate = self;// Set video encoding parameters to determine the picture quality seen by remote users.TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_960_540;encParam.videoFps = 15;encParam.videoBitrate = 1300;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera can specify using the front/rear camera for video capture.[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.anchorPreviewView];// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSIC.[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}
enterRoom
. The SDK will only start the camera preview and audio capture, and wait until you call enterRoom
to start streaming.enterRoom
. The SDK will start the camera preview and audio capture and automatically start streaming.- (void)setupRenderParams {TRTCRenderParams *params = [[TRTCRenderParams alloc] init];// Video mirror modeparams.mirrorType = TRTCVideoMirrorTypeAuto;// Video fill modeparams.fillMode = TRTCVideoFillMode_Fill;// Video rotation angleparams.rotation = TRTCVideoRotation_0;// Set the rendering parameters for the local video.[self.trtcCloud setLocalRenderParams:params];// Set the video mirror mode for the encoder output.[self.trtcCloud setVideoEncoderMirror:YES];// Set the rotation of the video encoder output.[self.trtcCloud setVideoEncoderRotation:TRTCVideoRotation_0];}
- (void)enterRoomByAnchorWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// Take the room ID string as an example.params.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backend.params.userSig = @"userSig";// Replace with your SDKAppID.params.sdkAppId = 0;// Specify the anchor role.params.role = TRTCRoleAnchor;// Enter the room in an interactive live streaming scenario.[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// Event callback for the result of entering the room.- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result indicates the time taken (in milliseconds) to join the room.NSLog(@"Enter room succeed!");} else {// result indicates the error code when you fail to enter the room.NSLog(@"Enter room failed!");}}
roomId
and string type strRoomId
. The rooms of these two types are not interconnected. It is recommended to unify the room ID type.TRTCAppSceneLIVE
as the room entry mode.- (void)startPublishMediaToCDN:(NSString *)streamName {NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];// Set the expiration time for the push URLs.NSTimeInterval time = [date timeIntervalSince1970] + (24 * 60 * 60);// Generate authentication information. The getSafeUrl method can be obtained in the CSS console - Domain Name Management - Push Configuration - Sample Code for Push URLs.NSString *secretParam = [self getSafeUrl:LIVE_URL_KEY streamName:streamName time:time];// The target URLs for media stream publication.TRTCPublishTarget* target = [[TRTCPublishTarget alloc] init];// The target URLs are set for relaying to CDN.target.mode = TRTCPublishBigStreamToCdn;TRTCPublishCdnUrl* cdnUrl = [[TRTCPublishCdnUrl alloc] init];// Construct push URLs (in RTMP format) to the live streaming service provider.cdnUrl.rtmpUrl = [NSString stringWithFormat:@"rtmp://%@/live/%@?%@", PUSH_DOMAIN, streamName, secretParam];// True means Tencent CSS push URLs, and false means third-party services.cdnUrl.isInternalLine = YES;NSMutableArray* cdnUrlList = [NSMutableArray array];// Multiple CDN push URLs can be added.[cdnUrlList addObject:cdnUrl];target.cdnUrlList = cdnUrlList;// Set media stream encoding output parameters (can be defined according to business needs).TRTCStreamEncoderParam* encoderParam = [[TRTCStreamEncoderParam alloc] init];encoderParam.audioEncodedSampleRate = 48000;encoderParam.audioEncodedChannelNum = 1;encoderParam.audioEncodedKbps = 50;encoderParam.audioEncodedCodecType = 0;encoderParam.videoEncodedWidth = 540;encoderParam.videoEncodedHeight = 960;encoderParam.videoEncodedFPS = 15;encoderParam.videoEncodedGOP = 2;encoderParam.videoEncodedKbps = 1300;// Start publishing media streams.[self.trtcCloud startPublishMediaStream:target encoderParam:encoderParam mixingConfig:nil];}
- (void)onStartPublishMediaStream:(NSString *)taskId code:(int)code message:(NSString *)message extraInfo:(NSDictionary *)extraInfo {// taskId: When the request is successful, TRTC backend will provide the taskId of this task in the callback. You can later use this taskId with updatePublishMediaStream and stopPublishMediaStream to update and stop.// code: Callback result. 0 means success and other values mean failure.}
// Initialize the player.self.livePlayer = [[V2TXLivePlayer alloc] init];// Set the player callback listener.[self.livePlayer setObserver:self];// Set the video rendering control for the player.[self.livePlayer setRenderView:self.remoteView];// Set delay management mode (optional).[self.livePlayer setCacheParams:1.f maxTime:5.f]; // Auto mode[self.livePlayer setCacheParams:1.f maxTime:1.f]; // Speed mode[self.livePlayer setCacheParams:5.f maxTime:5.f]; // Smooth mode// Concatenate the pull URLs for playback.NSString *flvUrl = [NSString stringWithFormat:@"http://%@/live/%@.flv", PLAY_DOMAIN, streamName];NSString *hlsUrl = [NSString stringWithFormat:@"http://%@/live/%@.m3u8", PLAY_DOMAIN, streamName];NSString *rtmpUrl = [NSString stringWithFormat:@"rtmp://%@/live/%@", PLAY_DOMAIN, streamName];NSString *webrtcUrl = [NSString stringWithFormat:@"webrtc://%@/live/%@", PLAY_DOMAIN, streamName];// Start playing.[self.livePlayer startLivePlay:flvUrl];// Custom set fill mode (optional).[self.livePlayer setRenderFillMode:V2TXLiveFillModeFit];// Custom video rendering direction (optional).[self.livePlayer setRenderRotation:V2TXLiveRotation0];
[TXLiveBase setLicenceURL:LICENSEURL key:LICENSEURLKEY];
// Enter the TRTC room and start streaming.- (void)enterRoomWithUserId:(NSString *)userId roomId:(NSString *)roomId {TRTCParams *params = [[TRTCParams alloc] init];// Take the room ID string as an example.params.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backend.params.userSig = @"userSig";// Replace with your SDKAppID.params.sdkAppId = 0;// Specify the anchor role.params.role = TRTCRoleAnchor;// Enable local audio and video capture.[self startLocalMedia];// Enter the room in an interactive live streaming scenario.[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}// Enable local video preview and audio capture.- (void)startLocalMedia {// Set video encoding parameters to determine the picture quality seen by remote users.TRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_480_270;encParam.videoFps = 15;encParam.videoBitrate = 550;encParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:encParam];// isFrontCamera can specify using the front/rear camera for video capture.[self.trtcCloud startLocalPreview:self.isFrontCamera view:self.audiencePreviewView];// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSIC.[self.trtcCloud startLocalAudio:TRTCAudioQualityDefault];}// Event callback for the result of entering the room.- (void)onEnterRoom:(NSInteger)result {if (result > 0) {// result indicates the time taken (in milliseconds) to join the room.NSLog(@"Enter room succeed!");} else {// result indicates the error code when you fail to enter the room.NSLog(@"Enter room failed!");}}
- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes their audio.// Under the automatic subscription mode, you do not need to do anything. The SDK will automatically play the remote user's audio.}- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes the primary video.if (available) {// Subscribe to the remote user's video stream and bind the video rendering control.[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteView];} else {// Unsubscribe to the remote user's video stream and release the rendering control.[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}- (void)onFirstVideoFrame:(NSString *)userId streamType:(TRTCVideoStreamType)streamType width:(int)width height:(int)height {// The SDK starts rendering the first frame of the local or remote user's video.if (![userId isEqualToString:@""]) {// Stop playing the CDN stream upon receiving the first frame of the anchor's video.[self.livePlayer stopPlay];}}
startRemoteView
can directly reuse the video rendering control previously used by the CDN stream pullingsetRenderView
.onFirstVideoFrame
is received before stopping the CDN stream pulling.// Event callback for the mic-connection audience's room entry.- (void)onRemoteUserEnterRoom:(NSString *)userId {if (![self.mixUserList containsObject:userId]) {[self.mixUserList addObject:userId];}[self updatePublishMediaToCDN];}// Update the publication of mixed media streams to the live streaming CDN.- (void)updatePublishMediaToCDN {NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];// Set the expiration time for the push URLs.NSTimeInterval time = [date timeIntervalSince1970] + (24 * 60 * 60);// Generate authentication information. The getSafeUrl method can be obtained in the CSS console - Domain Name Management - Push Configuration - Sample Code for Push URLs.NSString *secretParam = [self getSafeUrl:LIVE_URL_KEY streamName:self.streamName time:time];// The target URLs for media stream publication.TRTCPublishTarget* target = [[TRTCPublishTarget alloc] init];// The target URLs are set for relaying the mixed streams to CDN.target.mode = TRTCPublishMixStreamToCdn;TRTCPublishCdnUrl* cdnUrl = [[TRTCPublishCdnUrl alloc] init];// Construct push URLs (in RTMP format) to the live streaming service provider.cdnUrl.rtmpUrl = [NSString stringWithFormat:@"rtmp://%@/live/%@?%@", PUSH_DOMAIN, self.streamName, secretParam];// True means Tencent CSS push URLs, and false means third-party services.cdnUrl.isInternalLine = YES;NSMutableArray* cdnUrlList = [NSMutableArray array];// Multiple CDN push URLs can be added.[cdnUrlList addObject:cdnUrl];target.cdnUrlList = cdnUrlList;// Set media stream encoding output parameters.TRTCStreamEncoderParam* encoderParam = [[TRTCStreamEncoderParam alloc] init];encoderParam.audioEncodedSampleRate = 48000;encoderParam.audioEncodedChannelNum = 1;encoderParam.audioEncodedKbps = 50;encoderParam.audioEncodedCodecType = 0;encoderParam.videoEncodedWidth = 540;encoderParam.videoEncodedHeight = 960;encoderParam.videoEncodedFPS = 15;encoderParam.videoEncodedGOP = 2;encoderParam.videoEncodedKbps = 1300;TRTCStreamMixingConfig *config = [[TRTCStreamMixingConfig alloc] init];if (self.mixUserList.count) {NSMutableArray<TRTCUser *> *userList = [NSMutableArray array];NSMutableArray<TRTCVideoLayout *> *layoutList = [NSMutableArray array];for (int i = 1; i < MIN(self.mixUserList.count, 16); i++) {TRTCUser *user = [[TRTCUser alloc] init];// The integer room number is intRoomId.user.strRoomId = self.roomId;user.userId = self.mixUserList[i];[userList addObject:user];TRTCVideoLayout *layout = [[TRTCVideoLayout alloc] init];if ([self.mixUserList[i] isEqualToString:self.userId]) {// The layout for the anchor's video.layout.rect = CGRectMake(0, 0, 540, 960);layout.zOrder = 0;} else {// The layout for the mic-connection audience's video.layout.rect = CGRectMake(400, 5 + i * 245, 135, 240);layout.zOrder = 1;}layout.fixedVideoUser = user;layout.fixedVideoStreamType = TRTCVideoStreamTypeBig;[layoutList addObject:layout];}// Specify the information for each input audio stream in the transcoding stream.config.audioMixUserList = [userList copy];// Specify the information of position, size, layer, and stream type for each video screen in the mixed display.config.videoLayoutList = [layoutList copy];}// Update the published media stream.[self.trtcCloud updatePublishMediaStream:self.taskId publishTarget:target encoderParam:encoderParam mixingConfig:config];}// Event callback for updating the media stream.- (void)onUpdatePublishMediaStream:(NSString *)taskId code:(int)code message:(NSString *)message extraInfo:(NSDictionary *)extraInfo {// When you call the publish media stream API (updatePublishMediaStream), the taskId you provide will be returned to you through this callback. It is used to identify which update request the callback belongs to.// code: Callback result. 0 means success and other values mean failure.}
encoderParam
and the stream name streamName
unchanged.// Set the player callback listener.[self.livePlayer setObserver:self];// The reusable TRTC video rendering control.[self.livePlayer setRenderView:self.remoteView];// Restart playing CDN media stream.[self.livePlayer startLivePlay:flvUrl];- (void)onVideoLoading:(id<V2TXLivePlayer>)player extraInfo:(NSDictionary *)extraInfo {// Video loading event.}// Video playback event.- (void)onVideoPlaying:(id<V2TXLivePlayer>)player firstPlay:(BOOL)firstPlay extraInfo:(NSDictionary *)extraInfo {if (firstPlay) {[self.trtcCloud stopAllRemoteView];[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}}
onVideoPlaying
before exiting the TRTC room.// Event callback for the mic-connection audience's room exit.- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {if ([self.mixUserList containsObject:userId]) {[self.mixUserList removeObject:userId];}// The anchor updates the mixed stream task.[self updatePublishMediaToCDN];}// Event callback for updating the media stream.- (void)onUpdatePublishMediaStream:(NSString *)taskId code:(int)code message:(NSString *)message extraInfo:(NSDictionary *)extraInfo {// When you call the publish media stream API (updatePublishMediaStream), the taskId you provide will be returned to you through this callback. It is used to identify which update request the callback belongs to.// code: Callback result. 0 means success and other values mean failure.}
- (void)exitRoom {// Stop all published media streams.[self.trtcCloud stopPublishMediaStream:@""];[self.trtcCloud stopLocalAudio];[self.trtcCloud stopLocalPreview];[self.trtcCloud exitRoom];}// Event callback for stopping media streams.- (void)onStopPublishMediaStream:(NSString *)taskId code:(int)code message:(NSString *)message extraInfo:(NSDictionary *)extraInfo {// When you call the stop publishing media stream API (stopPublishMediaStream), the taskId you provide will be returned to you through this callback. It is used to identify which stop request the callback belongs to.// code: Callback result. 0 means success and other values mean failure.}// Event callback for exiting the room.- (void)onExitRoom:(NSInteger)reason {if (reason == 0) {NSLog(@"Proactively call exitRoom to exit the room.");} else if (reason == 1) {NSLog(@"Removed from the current room by the server.");} else if (reason == 2) {NSLog(@"The current room is dissolved.");}}
taskId
. This will stop all the media streams you have published.onExitRoom
callback notification to inform you.- (void)connectOtherRoom:(NSString *)roomId {NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];// The digit room ID is 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];}// Result callback for requesting cross-room mic-connection.- (void)onConnectOtherRoom:(NSString *)userId errCode:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {// The user ID of the anchor in the other room you want to initiate the cross-room link-up.// Error code. ERR_NULL indicates the request is successful.// Error message.}
- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes their audio.// Under the automatic subscription mode, you do not need to do anything. The SDK will automatically play the remote user's audio.}- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {// The remote user publishes/unpublishes the primary video.if (available) {// Subscribe to the remote user's video stream and bind the video rendering control.[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteView];} else {// Unsubscribe to the remote user's video stream and release the rendering control.[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}
// Exit the cross-room mic-connection.[self.trtcCloud disconnectOtherRoom];// Result callback for exiting cross-room mic-connection.- (void)onDisconnectOtherRoom:(TXLiteAVError)errCode errMsg:(NSString *)errMsg {}
DisconnectOtherRoom()
is called, you may exit the cross-room competition with all other room anchors.DisconnectOtherRoom()
to exit the cross-room competition.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};// Initialize the SDK: Width and height are the width and height of the texture, respectively.self.xMagicKit = [[XMagic alloc] initWithRenderSize:CGSizeMake(width,height) assetsDict:assetsDict];
// Set the video data callback for third-party beauty features in the TRTC SDK.[self.trtcCloud setLocalVideoProcessDelegete:self pixelFormat:TRTCVideoPixelFormat_Texture_2D bufferType:TRTCVideoBufferType_Texture];#pragma mark - TRTCVideoFrameDelegate// Construct the YTProcessInput and pass it into the SDK for rendering processing.- (uint32_t)onProcessVideoFrame:(TRTCVideoFrame *_Nonnull)srcFrame dstFrame:(TRTCVideoFrame *_Nonnull)dstFrame {if (!self.xMagicKit) {[self buildBeautySDK:srcFrame.width and:srcFrame.height texture:srcFrame.textureId];// Initialize 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 {// Video encoding parameters for the small-screen stream (customizable).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];}
// Optional video stream types when subscribing to a remote user's video stream.[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:view];// You can switch the size of the specified remote user's screen at any time.[self.trtcCloud setRemoteVideoStreamType:userId type:TRTCVideoStreamTypeSmall];
TRTCVideoStreamTypeSmall
with streamType
to pull a low-quality small video for viewing.// Update local preview screen rendering control.[self.trtcCloud updateLocalView:view];// Update the remote user's video rendering control.[self.trtcCloud updateRemoteView:view streamType:TRTCVideoStreamTypeBig forUser:userId];
view
refers to the target video rendering control. And streamType
only supports TRTCVideoStreamTypeBig
and TRTCVideoStreamTypeSub
.// Construct the likes message body.NSDictionary *msgDict = @{@"type": @1, // Like type@"likeCount": @10 // Number of likes};NSDictionary *dataDict = @{@"cmd": @"like_msg",@"msg": msgDict};NSError *error;NSData *data = [NSJSONSerialization dataWithJSONObject:dataDict options:0 error:&error];// Send custom group messages (it is recommended that like messages should be set to low priority).[[V2TIMManager sharedInstance] sendGroupCustomMessage:data to:groupID priority:V2TIM_PRIORITY_LOW succ:^{// Like messages sent successfully.// Local rendering of likes effect.} fail:^(int code, NSString *desc) {// Failed to send like messages.}];
// Custom group messages received.[[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"]; // Likes type.NSNumber *likeCount = msgDict[@"likeCount"]; // Number of likes.// Render likes effect based on likes type and count.}} else {NSLog(@"Parsing error: %@", 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", // The priority of the message. Gift messages should be set to high priority."MsgBody": [{"MsgType": "TIMCustomElem","MsgContent": {// type: gift type; giftUrl: gift resource URL; giftName: gift name; giftCount: number of gifts."Data": "{\\"cmd\\": \\"gift_msg\\", \\"msg\\": {\\"type\\": 1, \\"giftUrl\\": \\"xxx\\", \\"giftName\\": \\"xxx\\", \\"giftCount\\": 1}}"}}]}
// Custom group messages received.[[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"]; // Gift type.NSNumber *giftCount = msgDict[@"giftCount"]; // Number of gifts.NSString *giftUrl = msgDict[@"giftUrl"]; // Gift resource URL.NSString *giftName = msgDict[@"giftName"]; // Gift name.// Render gift effects based on gift type, count, resource URL, and name.}} else {NSLog(@"Parsing error: %@", error.localizedDescription);}}}
// Send public screen bullet screen messages.[[V2TIMManager sharedInstance] sendGroupTextMessage:text to:groupID priority:V2TIM_PRIORITY_NORMAL succ:^{// Successfully sent bullet screen messages.// Local display of the message text.} fail:^(int code, NSString *desc) {// Failed to send bullet screen messages.}];// Receive public screen bullet screen messages.[[V2TIMManager sharedInstance] addSimpleMsgListener:self];- (void)onRecvGroupTextMessage:(NSString *)msgID groupID:(NSString *)groupID sender:(V2TIMGroupMemberInfo *)info text:(NSString *)text {// Rendering bullet screen messages based on sender info and message text.}
onError
callback. For details, see Error Code Table.Enumeration | Value | Description |
ERR_TRTC_INVALID_USER_SIG | -3320 | Room entry parameter userSig is incorrect. Check if TRTCParams.userSig is empty. |
ERR_TRTC_USER_SIG_CHECK_FAILED | -100018 | UserSig verification failed. Check if the parameter TRTCParams.userSig is filled in correctly or has expired. |
Enumeration | Value | Description |
ERR_TRTC_CONNECT_SERVER_TIMEOUT | -3308 | Room entry request timed out. Check if your internet connection is lost or if a VPN is enabled. You may also attempt to switch to 4G for testing. |
ERR_TRTC_INVALID_SDK_APPID | -3317 | Room entry parameter sdkAppId is incorrect. Check if TRTCParams.sdkAppId is empty. |
ERR_TRTC_INVALID_ROOM_ID | -3318 | Room entry parameter roomId is incorrect. Check if TRTCParams.roomId or TRTCParams.strRoomId is empty. Note that roomId and strRoomId cannot be used interchangeably. |
ERR_TRTC_INVALID_USER_ID | -3319 | Room entry parameter userId is incorrect. Check if TRTCParams.userId is empty. |
ERR_TRTC_ENTER_ROOM_REFUSED | -3340 | Room entry request is denied. Check if enterRoom is called consecutively to enter rooms with the same ID. |
Enumeration | Value | Description |
ERR_CAMERA_START_FAIL | -1301 | Failed to open the camera. For example, if there is an exception for the camera's configuration program (driver) on a Windows or macOS device, you should try disabling then re-enabling the device, restarting the machine, or updating the configuration program. |
ERR_MIC_START_FAIL | -1302 | Failed to open the mic. For example, if there is an exception for the mic's configuration program (driver) on a Windows or macOS device, you should try disabling then re-enabling the device, restarting the machine, or updating the configuration program. |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | The device of camera is unauthorized. This typically occurs on mobile devices and may be due to the user having denied the permission. |
ERR_MIC_NOT_AUTHORIZED | -1317 | The device of mic is unauthorized. This typically occurs on mobile devices and may be due to the user having denied the permission. |
ERR_CAMERA_OCCUPY | -1316 | The camera is occupied. Try a different camera. |
ERR_MIC_OCCUPY | -1319 | The mic is occupied. This occurs when, for example, the user is currently having a call on the mobile device. |
setLocalRenderParams
and video encoding mirror setVideoEncoderMirror
. These settings individually affect the mirror effect of the local preview and the output of the video encoding (the mirror mode affects remote viewers and cloud recordings). If you expect the mirror effect seen in the local preview to also take effect on the remote viewer's end, follow these encoding procedures.// Set the rendering parameters for the local video.TRTCRenderParams *params = [[TRTCRenderParams alloc] init];params.mirrorType = TRTCVideoMirrorTypeEnable; // Video mirror modeparams.fillMode = TRTCVideoFillMode_Fill; // Video fill modeparams.rotation = TRTCVideoRotation_0; // Video rotation angle[self.trtcCloud setLocalRenderParams:params];// Set the video mirror mode for the encoder output.[self.trtcCloud setVideoEncoderMirror:YES];
// Get the maximum zoom factor for the camera (only for mobile devices).CGFloat zoomRatio = [[self.trtcCloud getDeviceManager] getCameraZoomMaxRatio];// Set the zoom factor for the camera (only for mobile devices).// Value range is 1 - 5. 1 means the furthest field of view (normal lens), and 5 means the closest field of view (zoom lens). The maximum recommended value is 5, exceeding this may result in blurry video.[[self.trtcCloud getDeviceManager] setCameraZoomRatio:zoomRatio];
// Enable or disable the camera's autofocus feature (only for mobile devices).[[self.trtcCloud getDeviceManager] enableCameraAutoFocus:NO];// Set the focus position of the camera (only for mobile devices).// The precondition for using this API is to first disable the autofocus feature using enableCameraAutoFocus.[[self.trtcCloud getDeviceManager] setCameraFocusPosition:CGPointMake(x, y)];
// Determine if the current camera is the front camera (only for mobile devices).BOOL isFrontCamera = [[self.trtcCloud getDeviceManager] isFrontCamera];// Switch to front or rear cameras (only for mobile devices).// Incoming true means switching to front, and incoming false means switching to rear.[[self.trtcCloud getDeviceManager] switchCamera:!isFrontCamera];
Was this page helpful?