TUILiveRoom
is an open-source audio/video UI component. After integrating it into your project, you can make your application support the interactive video live streaming scenario simply by writing a few lines of code. It also supports Android and Flutter platforms. Its basic features are as shown below:
![]() |
![]() |
![]() |
![]() |
TUILiveRoom
componentCreate the TUILiveRoom
folder at the same level as the Podfile
in your Xcode project, copy the TXAppBasic, TCBeautyKit, Resources, Source and TUIVoiceRoom.podspec files from the iOS
directory in the GitHub repository to the folder, and complete the following import operations:
Podfile
and import TUILiveRoom.podspec
as follows:# :path => "Points to the relative path of the directory of `TXAppBasic.podspec`"
pod 'TXAppBasic', :path => "TUILiveRoom/TXAppBasic/"
# :path => "Points to the relative path of the directory of `TCBeautyKit.podspec`"
pod 'TCBeautyKit', :path => "TUILiveRoom/TCBeautyKit/"
# :path => "Points to the relative path of the directory of `TUILiveRoom.podspec`"
pod 'TUILiveRoom', :path => "TUILiveRoom/", :subspecs => ["TRTC"]
Podfile
, and run pod install
.pod install
Add Privacy > Microphone Usage Description
(mic access request) and Privacy > Camera Usage Description
(camera access request) to the info.plist
file in sequence.
<key>NSMicrophoneUsageDescription</key>
<string>`TUILiveRoom` needs to access your mic to be able to shoot videos with audio.</string>
<key>NSCameraUsageDescription</key>
<string>`TUILiveRoom` needs to access your camera to be able to shoot videos with images.</string>
let mTRTCLiveRoom = TRTCLiveRoom()
// useCDNFirst: `true` means that the audience watches live streams over CDNs, and `false` means that the audience watches live streams in the low latency mode.
//CDNPlayDomain: The playback domain name for CDN live streaming
let config = TRTCLiveRoomConfig(useCDNFirst: useCDNFirst, cdnPlayDomain: yourCDNPlayDomain)
mTRTCLiveRoom.login(SDKAPPID, userID, userSig, config) { (code, error) in
if code == 0 {
// Logged in
}
}
Parameter description:
SDKAppID
is as shown below:SDKAppID
. On the Application Management page in the TRTC console, the SecretKey
is as shown below:SDKAppID
, userId
, and Secretkey
. You can click here to directly generate a debugging userSig
online, or you can calculate it on your own by referring to the demo project. For more information, see UserSig.The anchor starts streaming through TRTCLiveRoom#createRoom.
// 1. Set your username and profile photo as an anchor
mTRTCLiveRoom.setSelfProfile(name: "A", avatarURL: "faceUrl", callback: nil)
// 2. Enable camera preview and set beauty filters before streaming
let view = UIView()
parentView.add(view)
mTRTCLiveRoom.startCameraPreview(frontCamera: true, view: view, callback: nil)
mTRTCLiveRoom.getBeautyManager().setBeautyStyle(.nature)
mTRTCLiveRoom.getBeautyManager().setBeautyLevel(6)
// 3. Create a room
let param = TRTCCreateRoomParam(roomName: "Test room", coverUrl: "")
mTRTCLiveRoom.createRoom(roomID: 123456789, roomParam: param) { [weak self] (code, error) in
if code == 0 {
// 4. Start streaming and publish the streams to CDNs
self?.mTRTCLiveRoom.startPublish(streamID: mSelfUserId + "_stream", callback: nil)
}
}
Audience watches through TRTCLiveRoom#enterRoom.
// 1. Get the room list from the backend. Suppose it is `roomList`
var roomList: [UInt32] = GetRoomList()
// 2. Call `getRoomInfos` to get the details of the room
mTRTCLiveRoom.getRoomInfos(roomIDs: roomList, callback: { (code, msg, list) in
if code == 0 {
// After getting the room information, you can display on the anchor list page the anchor's nickname, profile photo, and other information
}
})
// 3. Select a `roomid` and enter the room
mTRTCLiveRoom.enterRoom(roomID: roomID, callback: callback)
// 4. After receiving the notification about the anchor’s entry, start playback
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onAnchorEnter userID: String) {
// 5. Play the anchor's video
mTRTCLiveRoom.startPlay(userID: userID, view: renderView, callback: nil)
}
Audience member and the anchor co-anchor together through TRTCLiveRoom#requestJoinAnchor.
// Audience:
// 1. The audience member sends a co-anchoring request
mTRTCLiveRoom.requestJoinAnchor(reason: mSelfUserId + "requested to co-anchor", responseCallback: { [weak self] (agreed, reason) in
// 4. The request is accepted by the anchor
if agreed {
// 5. The audience member turns on the camera and starts pushing streams
self?.mTRTCLiveRoom.startCameraPreview(frontCamera: true, view: localView, callback: nil)
self?.mTRTCLiveRoom.startPublish(streamID: streamID, callback: nil)
}
}, callback: callback)
// Anchor:
// 2. The anchor receives the co-anchoring request
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onRequestJoinAnchor user: TRTCLiveUserInfo, reason: String?, timeout: Double) {
// 3. The anchor accepts the co-anchoring request
mTRTCLiveRoom.responseJoinAnchor(userID: userID, agree: true, reason: "agreed to co-anchor")
}
// 6. The anchor receives a notification that the co-anchoring audience member has turned on the mic
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onAnchorEnter userID: String) {
// 7. The anchor plays the audience member’s video
mTRTCLiveRoom.startPlay(userID: userID, view: view, callback: nil)
}
Anchors compete through TRTCLiveRoom#requestRoomPK.
// Anchor A:
// Create room 12345
mTRTCLiveRoom.createRoom(roomID: 12345, roomParam: param, callback: nil)
// 1. Send a competition request to anchor B
mTRTCLiveRoom.requestRoomPK(roomID: 54321, userID: "B", responseCallback: { (agree, reason) in
// 5. Receive a callback of whether the request is accepted by anchor B
if agree {
}
}, callback: callback)
// Anchor A receives the callback of anchor B’s entry
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onAnchorEnter userID: String) {
// 6. After receiving the notification of anchor B’s entry, anchor A plays anchor B's video image
mTRTCLiveRoom.startPlay(userID: userID, view: view, callback: callback)
}
// Anchor B:
// Create room 54321
mTRTCLiveRoom.createRoom(roomID: 54321, roomParam: param, callback: nil)
// 2. Receive anchor A’s request
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onRequestRoomPK user: TRTCLiveUserInfo, timeout: Double) {
// 3. Accept anchor A's request
mTRTCLiveRoom.responseRoomPK(userID: userID, agree: true, reason: reason)
}
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onAnchorEnter userID: String) {
// 4. Receive a notification about anchor A’s entry and play anchor A's video
mTRTCLiveRoom.startPlay(userID: userID, view: view, callback: callback)
}
Implement text chat through TRTCLiveRoom#sendRoomTextMsg.
// Sender: Sends text messages
mTRTCLiveRoom.sendRoomTextMsg(message: "Hello Word!", callback: callback)
// Receiver: Listens for text messages
mTRTCLiveRoom.delegate = self
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onRecvRoomTextMsg message: String, fromUser user: TRTCLiveUserInfo) {
debugPrint("Received a text message from \(user.userName): \(message)")
}
Implement on-screen commenting through TRTCLiveRoom#sendRoomCustomMsg.
// Sender: Customize CMD to distinguish on-screen comments and likes
// For example, use "CMD_DANMU" to indicate on-screen comments and "CMD_LIKE" to indicate likes.
mTRTCLiveRoom.sendRoomCustomMsg(command: "CMD_DANMU", message: "Hello world", callback: nil)
mTRTCLiveRoom.sendRoomCustomMsg(command: "CMD_LIKE", message: "", callback: nil)
// Receiver: Listens for custom messages
mTRTCLiveRoom.delegate = self
public func trtcLiveRoom(_ trtcLiveRoom: TRTCLiveRoom, onRecvRoomCustomMsg command: String, message: String, fromUser user: TRTCLiveUserInfo) {
if "CMD_DANMU" == command {
// An on-screen comment is received
debugPrint("Received an on-screen comment from \(user.userName): \(message)")
} else if "CMD_LIKE" == command {
// A like is received
debugPrint("\(user.userName) liked you.")
}
}
If you have any requirements or feedback, contact colleenyu@tencent.com.
Was this page helpful?