製品アップデート情報
Tencent Cloudオーディオビデオ端末SDKの再生アップグレードおよび承認チェック追加に関するお知らせ
TRTCアプリケーションのサブスクリプションパッケージサービスのリリースに関する説明について
Concept | Tencent RTC Engine | Twilio Video | Description |
Room | Room | Room | Session space connecting RTC participants. Tencent RTC uses roomId (numeric) or strRoomId (string); Twilio uses roomName (string). |
User | User | Participant | User participating in audio/video calls. |
Anchor | Anchor | — | User type with streaming permission; can send and receive audio/video streams to/from the server. |
Audience | Audience | — | User type that only receives audio/video streams. |
Application Identifier | SDKAppID | Account SID | Unique application identifier. |
Authentication Credential | UserSig | Access Token | Client authentication credential. |
User Identifier | userId | Identity | Unique user identifier. |
Core Entry Class | TRTCCloud | Video (class) | SDK core entry class. |
LocalAudioTrack and LocalVideoTrack.ConnectOptions.Builder.RemoteParticipant.Listener.VideoSink or VideoView.startLocalPreview() and startLocalAudio() on the TRTCCloud singleton.TRTCCloudListener callbacks and startRemoteView().TXCloudVideoView.

source 'https://github.com/CocoaPods/Specs'platform :ios, '12.2'target 'TARGET_NAME' dopod 'TwilioVideo', '~> 5'end
sudo gem install cocoapods
pod init
platform :ios, '9.0'target 'YourApp' dopod 'TXLiteAVSDK_TRTC', :podspec => 'https://liteav.sdk.qcloud.com/pod/liteavsdkspec/TXLiteAVSDK_TRTC.podspec'end
pod install
pod install finishes, a new .xcworkspace file will be generated. Open the .xcworkspace file to continue development.
Info.plist, add Privacy-Microphone Usage Description and Privacy-Camera Usage Description. Fill in appropriate prompts for microphone and camera permissions.
Signing & Capabilities, add Background Modes and check Audio, AirPlay and Picture in Picture to enable background audio, AirPlay, and Picture in Picture features.
import TwilioVideoclass TwilioVideoManager {var room: Room?var localVideoTrack: LocalVideoTrack?var localAudioTrack: LocalAudioTrack?init() {// Twilio SDK does not require explicit initialization}}
import TXLiteAVSDK_TRTCclass TRTCManager: NSObject {// Obtain TRTCCloud singletonlet trtcCloud = TRTCCloud.sharedInstance()override init() {super.init()// Set event callback delegatetrtcCloud.delegate = self}}
#import <TXLiteAVSDK_TRTC/TRTCCloud.h>@interface TRTCManager : NSObject <TRTCCloudDelegate>@property (nonatomic, strong) TRTCCloud *trtcCloud;@end@implementation TRTCManager- (instancetype)init {self = [super init];if (self) {// Obtain TRTCCloud singleton_trtcCloud = [TRTCCloud sharedInstance];// Set event callback delegate_trtcCloud.delegate = self;}return self;}@end
@IBAction func connectToRoom(sender: AnyObject) {let connectOptions = ConnectOptions(token: accessToken) { (builder) inbuilder.roomName = "my-room"}room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)}
func enterRoom(sdkAppId: UInt32, roomId: UInt32, userId: String, userSig: String) {// Configure room parameterslet params = TRTCParams()params.sdkAppId = sdkAppIdparams.roomId = roomIdparams.userId = userIdparams.userSig = userSigparams.role = .anchor // Anchor role can publish streams// Enter room and specify scene// .videoCall - video call scene// .audioCall - audio call scene// .LIVE - live streaming scene// .voiceChatRoom - voice chat room scenetrtcCloud.enterRoom(params, appScene: .LIVE)}
- (void)enterRoomWithSdkAppId:(UInt32)sdkAppIdroomId:(UInt32)roomIduserId:(NSString *)userIduserSig:(NSString *)userSig {// Configure room parametersTRTCParams *params = [[TRTCParams alloc] init];params.sdkAppId = sdkAppId;params.roomId = roomId;params.userId = userId;params.userSig = userSig;params.role = TRTCRoleAnchor; // Anchor role can publish streams// Enter room and specify scene// TRTCAppSceneVideoCall - video call scene// TRTCAppSceneAudioCall - audio call scene// TRTCAppSceneLIVE - live streaming scene// TRTCAppSceneVoiceChatRoom - voice chat room scene[self.trtcCloud enterRoom:params appScene:TRTCAppSceneLIVE];}
extension TwilioVideoManager: RoomDelegate {// Successfully connected to roomfunc roomDidConnect(room: Room) {print("Connected to room: \\(room.name)")}// Disconnectedfunc roomDidDisconnect(room: Room, error: Error?) {print("Room connection disconnected")}// Connection failedfunc roomDidFailToConnect(room: Room, error: Error) {print("Connection failed: \\(error.localizedDescription)")}// Remote participant joinedfunc participantDidConnect(room: Room, participant: RemoteParticipant) {print("Participant joined: \\(participant.identity)")}// Remote participant leftfunc participantDidDisconnect(room: Room, participant: RemoteParticipant) {print("Participant left: \\(participant.identity)")}}
extension TRTCManager: TRTCCloudDelegate {// Room entry result callback// result > 0: Success (milliseconds)// result < 0: Failure (error code)func onEnterRoom(_ result: Int) {if result > 0 {print("Entered room successfully, time: \\(result)ms")} else {print("Failed to enter room, error code: \\(result)")}}// Room exit callback// reason: 0 - voluntary exit, 1 - kicked out, 2 - room dismissedfunc onExitRoom(_ reason: Int) {print("Exited room, reason: \\(reason)")}// Error callbackfunc onError(_ errCode: TXLiteAVError, errMsg: String?, extInfo: [AnyHashable: Any]?) {print("Error: \\(errCode.rawValue) - \\(errMsg ?? "")")}// Remote user entered roomfunc onRemoteUserEnterRoom(_ userId: String) {print("Remote user entered: \\(userId)")}// Remote user left roomfunc onRemoteUserLeaveRoom(_ userId: String, reason: Int) {print("Remote user left: \\(userId), reason: \\(reason)")}// Remote user video availability changedfunc onUserVideoAvailable(_ userId: String, available: Bool) {print("User \\(userId) video available: \\(available)")}// Remote user audio availability changedfunc onUserAudioAvailable(_ userId: String, available: Bool) {print("User \\(userId) audio available: \\(available)")}}
#pragma mark - TRTCCloudDelegate// Room entry result callback// result > 0: Success (milliseconds)// result < 0: Failure (error code)- (void)onEnterRoom:(NSInteger)result {if (result > 0) {NSLog(@"Entered room successfully, time: %ldms", (long)result);} else {NSLog(@"Failed to enter room, error code: %ld", (long)result);}}// Room exit callback// reason: 0 - voluntary exit, 1 - kicked out, 2 - room dismissed- (void)onExitRoom:(NSInteger)reason {NSLog(@"Exited room, reason: %ld", (long)reason);}// Error callback- (void)onError:(TXLiteAVError)errCode errMsg:(NSString *)errMsg extInfo:(NSDictionary *)extInfo {NSLog(@"Error: %d - %@", errCode, errMsg);}// Remote user entered room- (void)onRemoteUserEnterRoom:(NSString *)userId {NSLog(@"Remote user entered: %@", userId);}// Remote user left room- (void)onRemoteUserLeaveRoom:(NSString *)userId reason:(NSInteger)reason {NSLog(@"Remote user left: %@, reason: %ld", userId, (long)reason);}// Remote user video availability changed- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {NSLog(@"User %@ video available: %@", userId, available ? @"YES" : @"NO");}// Remote user audio availability changed- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {NSLog(@"User %@ audio available: %@", userId, available ? @"YES" : @"NO");}
// MARK: - Local Videofunc startPreview() {// Create camera sourcecamera = CameraSource(delegate: self)// Create local video tracklocalVideoTrack = LocalVideoTrack(source: camera!, enabled: true, name: "camera")// Add renderer to display previewlocalVideoTrack?.addRenderer(previewView)// Get front camera and start captureif let frontCamera = CameraSource.captureDevice(position: .front) {camera?.startCapture(device: frontCamera)}}func stopLocalVideo() {localVideoTrack?.isEnabled = false}// MARK: - Local Audiofunc startLocalAudio() {localAudioTrack = LocalAudioTrack()}func stopLocalAudio() {localAudioTrack?.isEnabled = false}func muteAudio(_ mute: Bool) {localAudioTrack?.isEnabled = !mute}
// MARK: - Local Videofunc startLocalVideo(view: UIView, frontCamera: Bool = true) {// Set local preview rendering parameters (optional, SDK provides defaults)let renderParams = TRTCRenderParams()renderParams.fillMode = .fill // .fill (fill) or .fit (fit)renderParams.mirrorType = .auto // .auto (front camera), .enable (always mirror), .disable (no mirror)trtcCloud.setLocalRenderParams(renderParams)// Start local video preview// frontCamera: true = front camera, false = rear cameratrtcCloud.startLocalPreview(frontCamera, view: view)}func stopLocalVideo() {trtcCloud.stopLocalPreview()}func muteLocalVideo(_ mute: Bool) {trtcCloud.muteLocalVideo(.big, mute: mute)}func switchCamera(_ frontCamera: Bool) {trtcCloud.getDeviceManager().switchCamera(frontCamera)}// MARK: - Local Audiofunc startLocalAudio(quality: TRTCAudioQuality = .default) {// quality options:// .speech - speech mode// .default - default mode// .music - music modetrtcCloud.startLocalAudio(quality)}func stopLocalAudio() {trtcCloud.stopLocalAudio()}func muteLocalAudio(_ mute: Bool) {trtcCloud.muteLocalAudio(mute)}
#pragma mark - Local Video- (void)startLocalVideoWithView:(UIView *)view frontCamera:(BOOL)frontCamera {// Set local preview rendering parameters (optional, SDK provides defaults)TRTCRenderParams *renderParams = [[TRTCRenderParams alloc] init];renderParams.fillMode = TRTCVideoFillMode_Fill;renderParams.mirrorType = TRTCVideoMirrorTypeAuto;[self.trtcCloud setLocalRenderParams:renderParams];// Start local video preview[self.trtcCloud startLocalPreview:frontCamera view:view];}- (void)stopLocalVideo {[self.trtcCloud stopLocalPreview];}- (void)muteLocalVideo:(BOOL)mute {[self.trtcCloud muteLocalVideo:TRTCVideoStreamTypeBig mute:mute];}- (void)switchCamera:(BOOL)frontCamera {[[self.trtcCloud getDeviceManager] switchCamera:frontCamera];}#pragma mark - Local Audio- (void)startLocalAudioWithQuality:(TRTCAudioQuality)quality {[self.trtcCloud startLocalAudio:quality];}- (void)stopLocalAudio {[self.trtcCloud stopLocalAudio];}- (void)muteLocalAudio:(BOOL)mute {[self.trtcCloud muteLocalAudio:mute];}
// MARK: - RemoteParticipantDelegateextension TwilioVideoManager: RemoteParticipantDelegate {// Track subscribedfunc didSubscribeToVideoTrack(videoTrack: RemoteVideoTrack,publication: RemoteVideoTrackPublication,participant: RemoteParticipant) {// Add renderer to display remote videovideoTrack.addRenderer(remoteVideoView)}// Track unsubscribedfunc didUnsubscribeFromVideoTrack(videoTrack: RemoteVideoTrack,publication: RemoteVideoTrackPublication,participant: RemoteParticipant) {videoTrack.removeRenderer(remoteVideoView)}}
extension TRTCManager: TRTCCloudDelegate {// Remote user video availability changedfunc onUserVideoAvailable(_ userId: String, available: Bool) {if available {// Subscribe to remote user's video stream// streamType: .big (main), .small (small), .sub (screen sharing)trtcCloud.startRemoteView(userId, streamType: .big, view: remoteVideoView)} else {// Stop subscription if video becomes unavailabletrtcCloud.stopRemoteView(userId, streamType: .big)}}// Remote user audio availability changedfunc onUserAudioAvailable(_ userId: String, available: Bool) {if available {// Audio auto-plays, use mute control as neededtrtcCloud.muteRemoteAudio(userId, mute: false)}}}// Manual control methodsfunc muteRemoteAudio(userId: String, mute: Bool) {trtcCloud.muteRemoteAudio(userId, mute: mute)}func muteAllRemoteAudio(_ mute: Bool) {trtcCloud.muteAllRemoteAudio(mute)
#pragma mark - TRTCCloudDelegate// Remote user video availability changed- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {if (available) {// Subscribe to remote user's video stream[self.trtcCloud startRemoteView:userId streamType:TRTCVideoStreamTypeBig view:self.remoteVideoView];} else {// Stop subscription if video becomes unavailable[self.trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeBig];}}// Remote user audio availability changed- (void)onUserAudioAvailable:(NSString *)userId available:(BOOL)available {if (available) {[self.trtcCloud muteRemoteAudio:userId mute:NO];}}// Manual control methods- (void)muteRemoteAudio:(NSString *)userId mute:(BOOL)mute {[self.trtcCloud muteRemoteAudio:userId mute:mute];}- (void)muteAllRemoteAudio:(BOOL)mute {[self.trtcCloud muteAllRemoteAudio:mute];}
func disconnect() {// Stop local trackslocalVideoTrack?.isEnabled = falselocalAudioTrack?.isEnabled = false// Disconnect room connectionroom?.disconnect()}extension TwilioVideoManager: RoomDelegate {func roomDidDisconnect(room: Room, error: Error?) {// Clean up resourceslocalVideoTrack = nillocalAudioTrack = nilself.room = nilif let error = error {print("Disconnected, error: \\(error.localizedDescription)")}}}
func exitRoom() {// Stop local preview and audio firsttrtcCloud.stopLocalPreview()trtcCloud.stopLocalAudio()// Leave the roomtrtcCloud.exitRoom()}extension TRTCManager: TRTCCloudDelegate {func onExitRoom(_ reason: Int) {// reason: 0 - called exitRoom(), 1 - kicked by server, 2 - room dismissedswitch reason {case 0:print("Exited room normally")case 1:print("Kicked by server")case 2:print("Room dismissed")default:break}}}class TRTCManager: NSObject {deinit {// Destroy instance after useTRTCCloud.destroySharedInstance()}}
- (void)exitRoom {// Stop local preview and audio first[self.trtcCloud stopLocalPreview];[self.trtcCloud stopLocalAudio];// Leave the room[self.trtcCloud exitRoom];}#pragma mark - TRTCCloudDelegate- (void)onExitRoom:(NSInteger)reason {// reason: 0 - called exitRoom, 1 - kicked by server, 2 - room dismissedswitch (reason) {case 0:NSLog(@"Exited room normally");break;case 1:NSLog(@"Kicked by server");break;case 2:NSLog(@"Room dismissed");break;default:break;}}- (void)dealloc {// Destroy instance after use[TRTCCloud destroySharedInstance];}
// Using ReplayKitletscreenCapturer = ReplayKitVideoSource(isScreencast: true)let screenTrack = LocalVideoTrack(source: screenCapturer)// Start broadcastRPScreenRecorder.shared().startCapture { sampleBuffer, bufferType, error in// Handle sample buffer}
// Configure screen sharing encoding parameterslet encParam = TRTCVideoEncParam()encParam.videoResolution = ._1280_720 // Recommended resolutionencParam.videoFps = 10 // Recommended frame rateencParam.videoBitrate = 1600 // Recommended bitrate (kbps)// Start system-wide screen sharing (requires Broadcast Extension and App Group)// streamType: .big (main stream) or .sub (auxiliary stream)// encParam: video encoding parameters// appGroup: App Group ID for communication between main app and extensiontrtcCloud.startScreenCapture(byReplaykit: .sub,encParam: encParam,appGroup: "group.your.app.identifier")// Stop screen sharingtrtcCloud.stopScreenCapture()
// Configure screen sharing encoding parametersTRTCVideoEncParam *encParam = [[TRTCVideoEncParam alloc] init];encParam.videoResolution = TRTCVideoResolution_1280_720;encParam.videoFps = 10;encParam.videoBitrate = 1600;// Start system-wide screen sharing (requires Broadcast Extension and App Group)- (void)startScreenCapture {TRTCVideoEncParam *videoEncConfig = [[TRTCVideoEncParam alloc] init];videoEncConfig.videoResolution = TRTCVideoResolution_1280_720;videoEncConfig.videoFps = 10;videoEncConfig.videoBitrate = 2000;// Replace `APPGROUP` with your App Group Identifier[[TRTCCloud sharedInstance] startScreenCaptureByReplaykit:videoEncConfigappGroup:APPGROUP];}// Stop screen sharing- (void)stopScreenCapture {[[TRTCCloud sharedInstance] stopScreenCapture];}
let connectOptions = ConnectOptions(token: token) { builder in// Video codec preferencebuilder.preferredVideoCodecs = [Vp8Codec(), H264Codec()]// Encoding parametersbuilder.encodingParameters = EncodingParameters(audioBitrate: 64,videoBitrate: 1500)}
// Video encoding parameterslet videoEncParam = TRTCVideoEncParam()videoEncParam.videoResolution = ._960_540 // ResolutionvideoEncParam.videoFps = 15 // Frame ratevideoEncParam.videoBitrate = 1200 // Video bitrate (kbps)videoEncParam.resMode = .portrait // Orientation modetrtcCloud.setVideoEncoderParam(videoEncParam)// Audio quality configuration (used in startLocalAudio)// .speech - speech mode// .default - default mode// .music - music modetrtcCloud.startLocalAudio(.music)
// Video encoding parametersTRTCVideoEncParam *videoEncParam = [[TRTCVideoEncParam alloc] init];videoEncParam.videoResolution = TRTCVideoResolution_960_540;videoEncParam.videoFps = 15;videoEncParam.videoBitrate = 1200;videoEncParam.resMode = TRTCVideoResolutionModePortrait;[self.trtcCloud setVideoEncoderParam:videoEncParam];// Audio quality configuration (used in startLocalAudio)[self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
// Switch cameraif let camera = camera {let newDevice = CameraSource.captureDevice(position: .back)camera.selectCaptureDevice(newDevice!) { _, _, error in// Handle result}}// MutelocalAudioTrack?.isEnabled = false// Switch to speaker (using AVAudioSession)do {try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)} catch { }
// Get device managerlet deviceManager = trtcCloud.getDeviceManager()// Switch front/rear cameradeviceManager.switchCamera(true) // true: front, false: rear// Check if current camera is frontlet isFront = deviceManager.isFrontCamera()// Set camera zoom ratio (1.0 - 5.0)deviceManager.setCameraZoomRatio(2.0)// Set camera focus positiondeviceManager.setCameraFocusPosition(CGPoint(x: 100, y: 100))// Flash controldeviceManager.enableCameraTorch(true)// Set auto focusdeviceManager.enableCameraAutoFocus(true)// MutetrtcCloud.muteLocalAudio(true)// Switch audio routetrtcCloud.setAudioRoute(.speakerphone) // SpeakertrtcCloud.setAudioRoute(.earpiece) // Earpiece
// Get device managerTXDeviceManager *deviceManager = [self.trtcCloud getDeviceManager];// Switch front/rear camera[deviceManager switchCamera:YES]; // YES: front, NO: rear// Check if current camera is frontBOOL isFront = [deviceManager isFrontCamera];// Set camera zoom ratio (1.0 - 5.0)[deviceManager setCameraZoomRatio:2.0];// Set camera focus position[deviceManager setCameraFocusPosition:CGPointMake(100, 100)];// Flash control[deviceManager enableCameraTorch:YES];// Set auto focus[deviceManager enableCameraAutoFocus:YES];// Mute[self.trtcCloud muteLocalAudio:YES];// Switch audio route[self.trtcCloud setAudioRoute:TRTCAudioModeSpeakerphone];[self.trtcCloud setAudioRoute:TRTCAudioModeEarpiece];
extension TwilioVideoManager: RoomDelegate {// Network quality change callbackfunc networkQualityLevelDidChange(participant: Participant,networkQualityLevel: NetworkQualityLevel) {// NetworkQualityLevel: .zero (unknown) ... .five (excellent)print("Participant \\(participant.identity) network quality: \\(networkQualityLevel.rawValue)")}}// Configure network quality monitoringlet connectOptions = ConnectOptions(token: token) { builder inbuilder.networkQualityEnabled = truebuilder.networkQualityConfiguration = NetworkQualityConfiguration(localVerbosity: .minimal,remoteVerbosity: .minimal)}
extension TRTCManager: TRTCCloudDelegate {// Network quality callback (triggered every 2 seconds)func onNetworkQuality(_ localQuality: TRTCQualityInfo,remoteQuality: [TRTCQualityInfo]) {// quality: 0=unknown, 1=excellent, 2=good, 3=average, 4=poor, 5=very poor, 6=unusableprint("Local network quality: \\(localQuality.quality.rawValue)")}// Statistics callbackfunc onStatistics(_ statistics: TRTCStatistics) {print("RTT: \\(statistics.rtt)ms")}}
// Listen to `onNetworkQuality` callback to monitor current network status- (void)onNetworkQuality:(TRTCQualityInfo *)localQuality remoteQuality:(NSArray<TRTCQualityInfo *> *)remoteQuality {switch(localQuality.quality) {case TRTCQuality_Unknown:NSLog(@"SDK has not yet detected the current network quality.");break;case TRTCQuality_Excellent:NSLog(@"The network is excellent.");break;case TRTCQuality_Good:NSLog(@"The network is good.");break;case TRTCQuality_Poor:NSLog(@"Network quality barely meets requirements.");break;case TRTCQuality_Bad:NSLog(@"Network is poor; expect significant lag and delays.");break;case TRTCQuality_VeryBad:NSLog(@"Network is very poor; communication quality can't be guaranteed.");break;case TRTCQuality_Down:NSLog(@"Network does not meet minimum requirements.");break;default:break;}for (TRTCQualityInfo *info in remoteQuality) {NSLog(@"remote user: %@, quality = %@", info.userId, @(info.quality));}}
class CustomVideoSource: NSObject, VideoSource {weak var sink: VideoSink?func sendFrame(_ pixelBuffer: CVPixelBuffer, timestamp: CMTime) {let frame = VideoFrame(timestamp: timestamp,buffer: pixelBuffer.videoFrameBuffer())sink?.onVideoFrame(frame)}}let customSource = CustomVideoSource()let videoTrack = LocalVideoTrack(source: customSource, enabled: true, name: "custom")
// Enable custom video capturetrtcCloud.enableCustomVideoCapture(.big, enable: true)// Send custom video frame (CVPixelBuffer)func sendCustomVideoFrame(_ pixelBuffer: CVPixelBuffer) {let videoFrame = TRTCVideoFrame()videoFrame.pixelFormat = ._NV12videoFrame.bufferType = .pixelBuffervideoFrame.pixelBuffer = pixelBuffertrtcCloud.sendCustomVideoData(.big, frame: videoFrame)}// Send custom video frame (texture)func sendCustomVideoTexture(_ textureId: GLuint, width: Int, height: Int) {let videoFrame = TRTCVideoFrame()videoFrame.pixelFormat = ._Texture_2DvideoFrame.bufferType = .texturevideoFrame.textureId = textureIdvideoFrame.width = UInt32(width)videoFrame.height = UInt32(height)trtcCloud.sendCustomVideoData(.big, frame: videoFrame)}// Stop custom capturetrtcCloud.enableCustomVideoCapture(.big, enable: false)
// Enable custom video capture[self.trtcCloud enableCustomVideoCapture:TRTCVideoStreamTypeBig enable:YES];// Send custom video frame- (void)sendCustomVideoFrame:(CVPixelBufferRef)pixelBuffer timestamp:(uint64_t)timestamp {TRTCVideoFrame *videoFrame = [[TRTCVideoFrame alloc] init];videoFrame.pixelFormat = TRTCVideoPixelFormat_NV12;videoFrame.bufferType = TRTCVideoBufferType_PixelBuffer;videoFrame.pixelBuffer = pixelBuffer;videoFrame.timestamp = timestamp;[self.trtcCloud sendCustomVideoData:TRTCVideoStreamTypeBig frame:videoFrame];}// Stop custom capture[self.trtcCloud enableCustomVideoCapture:TRTCVideoStreamTypeBig enable:NO];
let localDataTrack = LocalDataTrack(options: dataTrackOptions)localDataTrack?.send("Hello, World!")extension ViewController: RemoteDataTrackDelegate {func remoteDataTrackDidReceiveString(remoteDataTrack: RemoteDataTrack,message: String) {print("Received message: \\(message)")}}
// Send custom message (reliable transmission, to all users in the room)// cmdID: custom message ID (1-10)// data: message content, max 1KB// reliable: true for reliable transmission, false otherwise// ordered: true for ordered transmission, false otherwisetrtcCloud.sendCustomCmdMsg(1,data: "Hello, World!".data(using: .utf8)!,reliable: true,ordered: true)// Send SEI message (embedded in video frame, suitable for timestamp sync)// repeatCount: number of times to send, -1 means continuoustrtcCloud.sendSEIMsg("Timestamp: 12345".data(using: .utf8)!,repeatCount: 1)// Receive custom messageextension TRTCManager: TRTCCloudDelegate {func onRecvCustomCmdMsgUserId(_ userId: String,cmdID: Int,seq: UInt32,message: Data) {let text = String(data: message, encoding: .utf8) ?? ""print("Received message from \\(userId) [cmdID=\\(cmdID)]: \\(text)")}// Message loss callbackfunc onMissCustomCmdMsgUserId(_ userId: String,cmdID: Int,errCode: Int,missed: Int) {print("Lost \\(missed) messages from \\(userId)")}// Receive SEI messagefunc onRecvSEIMsg(_ userId: String, message: Data) {let text = String(data: message, encoding: .utf8) ?? ""print("Received SEI message: \\(text)")}}
- (void)sendHello {// Custom message command. Define rules as needed; here, 0x1 sends a text broadcastNSInteger cmdID = 0x1;NSData *data = [@"Hello" dataUsingEncoding:NSUTF8StringEncoding];[trtcCloud sendCustomCmdMsg:cmdID data:data reliable:YES ordered:YES];}// Send SEI message (embedded in video frame, suitable for timestamp sync)// repeatCount: number of times to send, -1 means continuous[self.trtcCloud sendSEIMsg:[@"Timestamp: 12345" dataUsingEncoding:NSUTF8StringEncoding]repeatCount:1];#pragma mark - TRTCCloudDelegate// Receive custom message- (void)onRecvCustomCmdMsgUserId:(NSString *)userIdcmdID:(NSInteger)cmdIDseq:(UInt32)seqmessage:(NSData *)message {NSString *text = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];NSLog(@"Received message from %@ [cmdID=%ld]: %@", userId, (long)cmdID, text);}// Message loss callback- (void)onMissCustomCmdMsgUserId:(NSString *)userIdcmdID:(NSInteger)cmdIDerrCode:(NSInteger)errCodemissed:(NSInteger)missed {NSLog(@"Lost %ld messages from %@", (long)missed, userId);}// Receive SEI message- (void)onRecvSEIMsg:(NSString *)userId message:(NSData *)message {NSString *text = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];NSLog(@"Received SEI message: %@", text);}
roomId): Integer between 1 and 4294967294 (recommended).strRoomId): Up to 64 bytes, supports letters, numbers, and select special characters.strRoomId.roomId and strRoomId in the same TRTC application; they are not interoperable.RemoteParticipant.Listener.onAudioTrackSubscribed callback. In TRTC, remote audio plays automatically after a user enters the room, with no extra action required. If you want to control audio playback for a specific remote user, use muteRemoteAudio(userId, true/false).Twilio Room Type | TRTC Application Scene | Applicable Scenario |
Peer-to-Peer Room | TRTCAppSceneVideoCall | 1v1 Video Call |
Peer-to-Peer Room (Audio Only) | TRTCAppSceneAudioCall | 1v1 Audio Call |
Group Room | TRTCAppSceneLIVE | Interactive Live Streaming, Multi-party Conference |
Group Room (Audio Only) | TRTCAppSceneVoiceChatRoom | Voice Chat Room |
onConnectionLost(): Connection to server lostonTryToReconnect(): Attempting to reconnectonConnectionRecovery(): Connection restoredonReconnecting and onReconnected callbacks.フィードバック