This section summarizes some common business processes in voice chat rooms to help you better understand the entire scenario implementation process.
Room Management Process
Room Owner Seat Management Process
Audience Seat Management Process
The following figure shows the room management process, including the creation, joining, exiting, and dissolvement of rooms.
The following figure shows the room owner seat management process, including inviting a listener to speak, removing a speaker, and muting a seat.
The following figure shows the audience seat management process, including becoming a speaker, become a listener, and moving a seat.
Integration Preparation
Step 1. Activating the Services
The voice chat room scenario typically depends on 2 paid PaaS services for construction, Chat and RTC Engine.
1. First, log in to the Console to create applications, wherein one is an RTC Engine application, and the other one is a Chat application.
Note:
It is recommended to create 2 separate applications for testing environment and production environment respectively. Each account (UIN) is given 10,000 free minutes monthly for one year.
RTC Engine monthly packages are divided into Trial Edition (default), Lite Edition, Standard Edition, and Professional Edition, unlocking different value-added features and services. For details, see Version Features and Monthly Package Description.
2. After an application is created, you can see the basic information of the application in the Application Management - Application Overview section. It is important to keep the SDKAppID and SDKSecretKey safe for later use and to avoid key leakage that could lead to traffic theft.
Step 2: Importing the SDK
The RTC Engine SDK and the Chat SDK have been published to the mavenCentral repository. You can configure gradle to download updates automatically.
1. Add the dependency for the appropriate version of the SDK in dependencies.
dependencies {
// TRTC Lite Edition SDK, including 2 features, TRTC and live streaming playback.
Quic plugin, offering axp-Quic multiplexing protocol with better resistance to poor networks, can still offer services under 70% packet loss rate. It's only applicable to Professional Edition, Professional Edition plus, and Enterprise Edition users. Purchase Pro Edition, Pro plus Edition ,or Enterprise Edition to use. To ensure normal usage of features, update the Chat SDK to version 7.7.5282 or later.
2. Specify the CPU architecture used by the app in defaultConfig.
defaultConfig {
ndk {
abiFilters "armeabi-v7a","arm64-v8a"
}
}
Note:
The RTC Engine SDK supports armeabi/armeabi-v7a/arm64-v8a architectures, and additionally supports x86/x86_64 architecture dedicated to simulators.
The Chat SDK supports armeabi-v7a/arm64-v8a/x86/x86_64 architectures. To reduce installation package size, you can choose to package SO files of some architecture.
Step 3: Project Configuration
1. Configure App permissions in AndroidManifest.xml. In voice chat scenarios, the RTC Engine SDK and the Chat SDK require the following permissions.
The RTC Engine SDK has no built-in permission request logic. You need to declare corresponding permissions and features. Some permissions (such as storage and recording) require dynamic requests during running.
If the Android project's targetSdkVersion is 31 or higher, or if the target device runs Android 12 or a newer version, the official requirement is to dynamically request android.permission.BLUETOOTH_CONNECT permission in the code to use the Bluetooth feature properly. For more information, see Bluetooth Permissions.
2. Since we use Java's reflection feature in the SDK, you should add relevant RTC Engine SDK classes to the non-obfuscation list in the proguard-rules.pro file.
-keep class com.tencent.**{*;}
Integration Process
Step 1: Generate Authentication Credentials
UserSig is a security protection signature designed by Tencent for real-time communication services to prevent attackers from stealing your right of using cloud services. RTC Engine and Chat services adopt this security protection mechanism, with RTC Engine performing authentication during room entry and Chat performing authentication during login.
Debugging Stage: UserSig can be generated through two methods for debugging and testing purposes only: client sample code and console access.
Formal Operation Stage: It is recommended to use a higher security level server computation for generating UserSig. This is to prevent key leakage due to client reverse engineering.
The specific implementation process is as follows:
1. Before calling the SDK's initialization function, your app must first request UserSig from your server.
2. Your server computes the UserSig based on the SDKAppID and UserID.
3. The server returns the computed UserSig to your app.
4. Your app passes the obtained UserSig into the SDK through a specific API.
5. The SDK submits the SDKAppID + UserID + UserSig to Tencent Cloud CVM for verification.
6. Tencent Cloud verifies the UserSig and confirms its validity.
7. After the verification passes, the Chat SDK will be provided with instant messaging services, and the RTC Engine SDK will be provided with Tencent Real-Time Communication (TRTC) services.
Note:
The local computation method of UserSig during the debugging stage is not recommended for application in an online environment. It is prone to reverse engineering, leading to key leakage.
We provide UserSig server-side computation source code in multiple languages (Java/Go/PHP/Node.js/Python/C#/C++). For details, see Server-Side Calculation of UserSig.
Step 2: Initialization and Listening
Sequence Diagram
1. Initialize the Chat SDK and add an event listener.
If your application's lifecycle is consistent with the SDK's lifecycle, you do not need to deinitialize before exiting the application. If you only initialize the SDK after entering a specific interface and no longer use it after exiting, you may deinitialize the SDK.
2. Create an RTC Engine SDK instance and set an event listener.
// Create an RTC Engine SDK instance (singleton mode)
// Terminate the RTC Engine SDK instance (singleton mode)
TRTCCloud.destroySharedInstance();
Note:
It is recommended to listen to SDK event notifications. Perform log printing and handling for some common errors. For details, see Error Code Table.
Step 3: Log In and Log Out
After initializing the Chat SDK, you need to call the SDK login API to authenticate account identity and obtain permissions to use features of the account. Therefore, before using other features, ensure successful login. Otherwise, feature malfunction or unavailability may occur. If you only need to use the RTC Engine audio and video service, you can skip this step.
Sequence Diagram
1. Log in.
// Log in: userID can be defined by the user and userSig can be generated as per Step 1.
If your application's lifecycle matches the Chat SDK's lifecycle, you do not need to log out before exiting the application. If you only use the Chat SDK after entering a specific interface and no longer use it after exiting the interface, you can log out and deinitialize the Chat SDK.
Step 4: Room Management
Sequence Diagram
1. Create a room.
The anchor (room owner) needs to create a room when going live. Here, the concept of "room" corresponds to "group" in Chat. This example only shows the way to create a Chat group on the client side. It can also be done via server-side group creation.
// Group creation callback. GroupID is the ID of the newly created group.
}
});
Note:
To create a Chat group for a voice chat room scenario, select the live streaming group type GROUP_TYPE_AVCHATROOM.
The RTC Engine does not provide a room-creation API. When a user attempts to join a room that does not exist, the backend automatically creates a room.
// Event callback for the result of entering the room.
@Override
publicvoidonEnterRoom(long result){
if(result >0){
// Result indicates the time taken (in milliseconds) to join the room.
Log.d(TAG,"Enter room succeed");
}else{
// Result indicates the error code in the case of room entry failure.
Log.d(TAG,"Enter room failed");
}
}
Note:
RTC Engine room IDs are divided into integer type roomId and string type strRoomId. Rooms of different types are not interconnected. It is advisable to unify the room ID type.
When entering a room in voice chat interaction scenarios, it is necessary to specify the user's role (anchor/audience). Only anchors have permissions to push streams. If not specified, the default role is anchor.
For voice chat interaction room-entering scenarios, it is recommended to use TRTC_APP_SCENE_VOICE_CHATROOM.
In a live streaming group (AVChatRoom), the group owner cannot exit the group. The owner can only dissolve the group by calling dismissGroup.
Exit an RTC Engine room.
privatevoidexitRoom(){
mTRTCCloud.stopLocalAudio();
mTRTCCloud.exitRoom();
}
// Event callback for exiting the room.
@Override
publicvoidonExitRoom(int reason){
if(reason ==0){
Log.d(TAG,"Actively call exitRoom to exit the room.");
}elseif(reason ==1){
Log.d(TAG,"Removed from the current room by the server.");
}elseif(reason ==2){
Log.d(TAG,"The current room has been dissolved.");
}
}
Note:
After all resources occupied by the SDK are released, the SDK will throw the onExitRoom callback notification to inform you.
If you want to call 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.
4. Dissolve the room.
Dissolve a Chat group.
This example only shows the way to dissolve a Chat group on the client side. It can also be done via server-side group dissolving.
Server-side dissolving: RTC Engine provides the server-side room dissolving API DismissRoom (distinguish between numeric room ID and string room ID). You can call this API to remove all users from the room and dissolve the room.
Client dissolving: Complete room exit for all anchors and audiences in the room via the room exit API exitRoom of each client. After room exit, the room will be automatically dissolved according to RTC Engine room lifecycle rules. For details, see Exit the Room.
Warning:
It is recommended that after the end of live streaming, you call the room dissolvement API to ensure the room is dissolved. This will prevent audiences from accidentally entering the room and incurring unexpected charges.
Step 5: Seat Management
Sequence Diagram
First, we can create a JavaBean to save seat information.
publicclassSeatInfoimplementsSerializable{
publicstaticfinaltransientint STATUS_UNUSED =0;
publicstaticfinaltransientint STATUS_USED =1;
publicstaticfinaltransientint STATUS_LOCKED =2;
// The status of seats. Three corresponding statuses are available.
publicint status;
// Whether the seat is muted.
publicboolean mute;
// When the seat is occupied, the user information is stored.
publicString userId;
@Override
publicStringtoString(){
return"TXSeatInfo{"
+"status="+ status
+", mute="+ mute
+", user='"+ userId +'\''
+'}';
}
}
1. Join a voice chat actively.
Becoming a speaker refers to off-mic audience sending a request to speak to the room owner or administrator. The audience can speak once the approval signaling is received. In a free-speaking mode, the signaling request part can be skipped.
Listener sends a request to become a speaker.
// Audience sends a request to speak. userId is the Anchor ID, and data can pass in a JSON identifying the signaling.
If the anchor agrees to the audience's request to speak, the audience can add seat information by modifying group attributes. Other users will receive a callback for the change in group attributes. Update the local seat information.
Anchor brings someone to a voice chat (with no listener consent required), directly modifies the seat information saved in group attributes. After matching the userId successfully upon receiving the group attribute change callback, the corresponding listener can switch the RTC Engine role and start streaming. In an invite-to-speak mode, refer to the implementation logic of becoming a speaker. Just switch the sender and recipient of the signaling.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
// Anchor calls this API to modify the seat information saved in group attributes.
privatevoidpickSeat(String userId,int seatIndex){
// Create a seat information instance. Store the modified seat information.
// Update the local seat list. Render local seat view.
}
}
}
}
});
3. Leave a voice chat actively.
Mic-connecting audiences can reset seat information by modifying group attributes. Other users will receive a group attribute change callback. Update local seat information.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
privatevoidleaveSeat(int seatIndex){
// Create a seat information instance. Store the modified seat information.
Anchor removes a speaker. Directly modify the seat information saved in group attributes. After matching the userId successfully upon receiving the group attribute change callback, the corresponding listener can switch the RTC Engine role and stop streaming.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
// Anchor calls this API to modify the seat information saved in group attributes.
privatevoidkickSeat(int seatIndex){
// Create a seat information instance. Store the modified seat information.
// Update the local seat list. Render local seat view.
}
}
}
}
});
5. Mute the mic.
Anchor mutes/unmutes a specific seat. Directly modify the seat information saved in group attributes. Corresponding mic-connecting audience receives group attribute change callback. After successfully matching userId, they pause/resume local streaming.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
// Anchor calls this API to modify the seat information saved in group attributes.
privatevoidmuteSeat(int seatIndex,boolean mute){
// Create a seat information instance. Store the modified seat information.
// Failed to modify group attributes. Failed to mute seats.
}
@Override
publicvoidonSuccess(){
// Group attributes modified successfully. Trigger onGroupAttributeChanged callback.
}
});
}
// The mic-connecting audience receives the group attribute change callback. The audience pauses/resumes streaming after successfully matching own information.
// Iterate through the full seat information list. Compare old and new seat information.
for(int i =0; i < seatSize; i++){
SeatInfo oldInfo = oldSeatInfoList.get(i);
SeatInfo newInfo = newSeatInfoList.get(i);
if(oldInfo.mute != newInfo.mute){
if(oldInfo.userId.equals(mUserId)){
// Its own information matched successfully. Pause/ restore local streaming.
mTRTCCloud.muteLocalAudio(newInfo.mute);
}else{
// Update the local seat list. Render local seat view.
}
}
}
}
});
6. Lock the mic.
Anchor locks/unlocks a seat by directly modifying the seat information saved in group attributes. Audience updates the corresponding seat view after receiving the group attribute change callback.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
// Anchor calls this API to modify the seat information saved in group attributes.
On-mic anchor moves a seat by necessarily and separately modifying the source and target seat information saved in group attributes. Audience updates the corresponding seat view after receiving the group attribute change callback.
// Locally saved full list of seats.
privateList<SeatInfo> mSeatInfoList;
// On-mic anchor calls this API to modify the seat information saved in group attributes.
// Failed to modify group attributes. Failed to move seats.
}
@Override
publicvoidonSuccess(){
// Group attributes modified successfully. Seats moved successfully.
}
});
}
Step 6: Audio Management
Sequence Diagram
1. Subscription mode.
The RTC Engine SDK defaults to automatic subscription of audio streams. Users automatically play remote users' voice when joining a room. For manual subscription to audio streams, calling muteRemoteAudio(userId, mute) additionally is required to subscribe and play remote users' audio streams.
// Automatic subscription mode (default).
mTRTCCloud.setDefaultStreamRecvMode(true,true);
// Manual subscription mode (custom).
mTRTCCloud.setDefaultStreamRecvMode(false,false);
Note:
Set the subscription mode setDefaultStreamRecvMode before entering the room enterRoom to ensure to take effect.
startLocalAudio requests mic permissions, and stopLocalAudio releases them.
3. Mute and unmute.
// Pause publishing local audio streams (mute).
mTRTCCloud.muteLocalAudio(true);
// Resume publishing local audio streams (unmute).
mTRTCCloud.muteLocalAudio(false);
// Pause the subscription and playback of a specific remote user's audio streams.
mTRTCCloud.muteRemoteAudio(userId,true);
// Resume the subscription and playback of a specific remote user's audio streams.
mTRTCCloud.muteRemoteAudio(userId,false);
// Pause the subscription and playback of all remote users' audio streams.
mTRTCCloud.muteAllRemoteAudio(true);
// Resume the subscription and playback of all remote users' audio streams.
mTRTCCloud.muteAllRemoteAudio(false);
Note:
In comparison, muteLocalAudio only requires a pause or release of the data stream at the software level, thus it is more efficient and smoother. And it is better suited for scenarios that require frequent muting and unmuting.
4. Audio quality and volume type.
Audio quality setting
// Set audio quality during local audio capture and publishing.
The RTC Engine offers 3 preset audio quality levels (Speech/Default/Music), corresponding to different audio parameters. For details, see TRTCAudioQuality.
Volume type setting.
Each RTC Engine audio quality level corresponds to a default volume type. If you need to forcibly specify a volume type, you can use the following API.
The RTC Engine offers 3 volume type levels (VOIP/Auto/Media), corresponding to different volume channels. For details, see TRTCSystemVolumeType.
Audio routing setting.
Mobile devices such as smartphones usually have two playback locations: the speaker and the earpiece. If you need to forcibly specify the audio routing, you can use the following API.
The RTC Engine offers two audio routes (Speaker/Earpiece), corresponding to different sound emission locations. For details, see TRTCAudioRoute.
Advanced Features
Bullet Screen Message Interaction
Voice chat live streaming rooms usually provide text-based bullet screen message interactions, which can be achieved by sending and receiving group chat plain text messages through Chat.
RTC Engine can callback the volume levels of the on-mic anchor at a fixed frequency. It is usually used to display sound waves and indicate the speaking anchor.
// Enable volume level callback. It is recommended to be enabled immediately after successful room entry.
// userVolumes is used to handle the volume levels of all speaking users, including both local users and remote streaming users.
// totalVolume is used to report the maximum volume value among remote streaming users.
...
// Display sound waves on the UI based on volume levels.
...
}
}
Note:
Voice detection only provides local voice detection results. The user's role must be an anchor to make it convenient to remind users to turn on their mics.
userVolumes is an array. For each element in the array, when userId is oneself, it indicates the volume captured by the local microphone; when userId is others, it indicates the volume of remote users.
Music and Sound Effect Playback
Playing background music and sound effects is a high-frequency demand in voice chat room scenarios. Below, we will explain the use of and precautions for commonly used background music APIs.
1. Start/stop/pause/resume playback.
// Obtain the management class for configuring background music, short sound effects, and voice special effects.
// Whether to publish the music to remote (otherwise play locally only).
param.publish =true;
// Whether the playback is from a short sound effect file.
param.isShortFile =false;
// Start background music playback.
mTXAudioEffectManager.startPlayMusic(param);
// Stop background music playback.
mTXAudioEffectManager.stopPlayMusic(musicID);
// Pause background music playback.
mTXAudioEffectManager.pausePlayMusic(musicID);
// Resume background music playback.
mTXAudioEffectManager.resumePlayMusic(musicID);
Note:
The RTC Engine supports playing multiple music tracks simultaneously, identified uniquely by musicID. To play only one piece of music at a time, stop other music before starting playback. Alternatively, use the same musicID to play different music. In this way, the SDK will stop the previous music first, then play the next music.
The RTC Engine supports playing local and network audio files. Use musicPath to input a local absolute path or URL address. Supported formats include MP3/AAC/M4A/WAV.
2. Adjust the ratio of music and voice volume.
// Set the local playback volume of a piece of background music.
// curPtsMS current playback duration (in milliseconds).
// durationMs: Total duration of the current music (in milliseconds).
}
@Override
// Background music has finished playing.
publicvoidonComplete(int id,int errCode){
// Playback failure due to weak network during playback will also throw this callback. In this case, errCode < 0.
// Pausing or stopping playback midway will not trigger the onComplete callback.
}
});
Note:
Use this API to set the playback event callback before playing background music to monitor the progress of the music;
If the MusicId does not need to be reused, you can execute setMusicObserver(musicId, null) after playback is finished to completely release the Observer.
4. Loop playback of background music and sound effects.
Solution 1: Use the AudioMusicParam's loopCount parameter to set the number of loop playbacks.
The value range is from 0 to any positive integer. The default value is 0. 0 means play the music once; 1 means play the music twice; and so on.
Solution 1 will not trigger the onComplete callback after each loop playback. It will only be triggered after all the set loop counts have been played.
Solution 2: Implement loop playback through the "Background music has finished playing" event callback onComplete. It is usually used for list loop or single track loop.
// The member variable used for indicating whether to loop playback.
// taskId: When the request is successful, TRTC backend will provide you 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.
// When you call the media stream publishing 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.
// When you call the media stream publishing stopping 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.
}
}
Update published media streams.
This API sends a command to the RTC Engine server to update the media stream initiated by startPublishMediaStream.
// taskId: Task ID returned by the onStartPublishMediaStream callback.
// target: For example, add or remove the published CDN URLs.
// params: It is recommended to maintain consistency in the encoding output parameters for the media stream to avoid interruptions during playback.
// config: Update the list of users involved in mix stream transcoding, such as cross-room PK.
Switching between audio only, audio and video, and video only is not supported within the same task.
Stop publishing media stream.
This API sends a command to the RTC Engine server to stop the media stream initiated by startPublishMediaStream.
// taskId: Task ID returned by the onStartPublishMediaStream callback.
mTRTCCloud.stopPublishMediaStream(taskId);
Note:
If taskId is filled with an empty string, it will stop all media streams initiated by the user through startPublishMediaStream. If you have only initiated one media stream or want to stop all media streams initiated by you, this method is recommended.
Real-Time Network Quality Callback
You can listen to onNetworkQuality to real-time monitor the network quality of both local and remote users. This callback is thrown every 2 seconds.
// localQuality userId is empty. It represents the local user's network quality evaluation result.
// remoteQuality represents the remote user's network quality evaluation result. The result is affected by both remote and local factors.
switch(localQuality.quality){
caseTRTCCloudDef.TRTC_QUALITY_Excellent:
Log.i(TAG,"The current network is excellent.");
break;
caseTRTCCloudDef.TRTC_QUALITY_Good:
Log.i(TAG,"The current network is good.");
break;
caseTRTCCloudDef.TRTC_QUALITY_Poor:
Log.i(TAG,"The current network is moderate.");
break;
caseTRTCCloudDef.TRTC_QUALITY_Bad:
Log.i(TAG,"The current network is poor.");
break;
caseTRTCCloudDef.TRTC_QUALITY_Vbad:
Log.i(TAG,"The current network is very poor.");
break;
caseTRTCCloudDef.TRTC_QUALITY_Down:
Log.i(TAG,"The current network does not meet the minimum requirements of TRTC.");
break;
default:
Log.i(TAG,"Undefined");
break;
}
}
}
Advanced Permission Control
RTC Engine advanced permission control can be used to set different entry permissions for different rooms, such as advanced VIP rooms. It can also control the permission for audience to speak, such as handling ganchor mics.
Step 1: Enable the advanced permission control switch on the feature configuration page of the application in the RTC Engine Console.
When the RTC Engine SDK encounters an unrecoverable error, the error is thrown in the onError callback. For details, see Error Code Table.
UserSig related
UserSig verification failure will lead to room-entering failure. You can use the UserSig tool for verification.
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.
Room entry and exit related
If failed to enter the room, you should first verify the correctness of the room entry parameters. It is essential that the room entry and exit APIs are called in a paired manner. This means that, even in the event of a failed room entry, the room exit API must still be called.
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 denied. Check if enterRoom is called consecutively to enter a room with the same ID.
Device related
Errors for relevant monitoring devices. Prompt the user via UI in case of relevant errors.
Enumeration
Value
Description
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_SPEAKER_START_FAIL
-1321
Failed to open the speaker. For example, if there is an exception for the speaker'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_OCCUPY
-1319
The mic is occupied. This occurs when, for example, the user is currently having a call on the mobile device.
Exception Exit Handling
1. Be aware of network disconnection and exit the room upon timeout.
You can monitor RTC Engine network disconnection and reconnection events through the following callback.
Upon receiving the onConnectionLost callback, display a network disconnection icon on the local seat UI to notify the user. Simultaneously, initiate a local timer. If the onConnectionRecovery callback is not received after exceeding the set time threshold, it means the network remains disconnected. Then, locally initiate leaving the seat and room exit process. Pop up a window to inform the user that they have exited the room and the page will be closed. If the disconnection exceeds 90 seconds (default), a timeout room-exit will be triggered, and the RTC Engine server side will remove the user from the room. If the user has an anchor role, other users in the room will receive the onRemoteUserLeaveRoom callback.
// The connection between the SDK and the cloud has been disconnected.
}
@Override
publicvoidonTryToReconnect(){
// The SDK is attempting to reconnect to the cloud.
}
@Override
publicvoidonConnectionRecovery(){
// The connection between the SDK and the cloud has been restored.
}
}
2. Automatically leave the voice chat when offline.
Chat user status is divided into online (ONLINE), offline (OFFLINE), and not logged in (UNLOGGED). Among them, the offline status is usually caused by user force-stopping process or abnormal network disruption. You can detect offline mic-connecting audiences through the features of anchors subscribing to the connection status of mic-connecting audiences, thereby removing them.
// Anchor subscribes to the connection status of mic-connecting audiences.
User status subscription needs to be upgraded to the Professional Edition package. For details, see Basic Service Details.
User status subscription needs enabling User Profile Change Subscription in the Chat Console in advance. Failure to enable it will result in an error when subscribeUserStatus is called.
Server Removes Users From and Dissolve the Room
1. Remove someone through the server side.
First, call the RTC Engine server-side user removing API RemoveUser (for integer room IDs) or RemoveUserByStrRoomId (for string room IDs) to remove the target user from the RTC Engine room. The input example is as follows:
After the user is removed successfully, the target user on the client will receive the onExitRoom() callback with reason set to 1. You can handle leaving the seat and exiting the Chat group in this callback.
// Exit TRTC room event callback.
@Override
publicvoidonExitRoom(int reason){
if(reason ==0){
Log.d(TAG,"Actively call exitRoom to exit the room.");
}else{
// reason 1: Removed from the current room by the server.
// reason 2: The current room is dissolved.
Log.d(TAG,"Being removed from the room by the server, or the current room having been dissolved.");
// Leave the seat.
leaveSeat(seatIndex);
// Exit the Chat group.
quitGroup(groupID,newV2TIMCallback(){});
}
}
2. Dissolve the room on the server side.
First call the Chat server-side group dissolving API destroy_group to dissolve the target group. The request URL example is as follows:
After the group is dissolved, all members within the target group will receive the onGroupDismissed() callback on clients. At this point, you can handle operations such as exiting the TRTC room in this callback.
When all users in the room call exitRoom() to complete room exit, the RTC Engine room will be automatically dissolved. Of course, you can also call the server-side API DismissRoom (room ID in integer type) or DismissRoomByStrRoomId (string room ID) to mandatorily dissolve the RTC Engine room.
View Live Streaming Room'S Historical Messages Upon Room Entry
By default, using AVChatRoom does not store live streaming room's historical messages. Therefore, when new users enter the live streaming room, they can only see messages sent after their entry. To optimize the experience for new users joining the group, you can configure the number of messages new live streaming group users can pull before joining the group in the console, as shown in the figure:
Pulling historical messages before joining the live streaming group for live streaming group users is the same as pulling historical messages for other groups. The sample code is:
This feature is only available to advanced users. It only supports pulling up to 20 historical messages within 24 hours from the group.
Sense the Mute Status of Anchors When They Enter the Room
Solution 1: Mute all anchors by default when they enter the room, then unmute the corresponding anchor based on the onUserAudioAvailable(userId, true) callback.
Solution 2: Store the anchor's mute status in the RTC Engine group attribute. When the audience enters the room, obtain all group attributes and parse the mute status of on-mic anchors.
// Successfully obtained group attributes. Assume the key for storing anchor mute status is muteStatus.
String muteStatus = attrMap.get("muteStatus");
// Parse muteStatus, and obtain the mute status of each on-mic anchor.
}
});
Bluetooth Headphone Audio Input/Output Issues
The mobile phone has successfully connected to the Bluetooth headphones, but the audio input or output of the RTC-Engine application still uses the mobile phone's microphone or speaker.
1. If the audio output is working fine with the Bluetooth headphones, but only the audio input is still using the mobile phone's microphone, check the settings for the audio volume type. Only under the call volume mode does it support capturing audio through the microphone on the Bluetooth headphones. For details, see Audio Management - Audio Quality and Volume Type.
2. If audio input and output fail to use Bluetooth headphones, check whether Bluetooth permissions are granted in the App permissions. For Android devices, systems earlier than Android 12 require at least the BLUETOOTH permission, and Android 12 or later systems require at least the BLUETOOTH_CONNECT permission and need to request permissions dynamically in the code.
To configure Bluetooth permissions in the AndroidManifest.xml for compatibility with systems below Android 12, it is recommended to declare permissions as follows:
<!--Normal Permission: basic Bluetooth connection permissions-->
<!--Runtime Permission: Android 12 Bluetooth permissions for communicating with paired Bluetooth devices or checking if Bluetooth is enabled on the current mobile phone-->
When the RTC Engine SDK API startPlayMusic is used to play background music, the music resource path parameter path does not support the passing of the path of files in directories for storing application resource files such as assets/raw for Android development. This is because files in these directories are bundled into the APK and are not extracted to the mobile's file system after installation. Currently, only network resource URLs and absolute paths to resource files as external storage of Android devices, and resource files in the application's private directory are supported.
You can work around this issue by copying resource files from the assets directory to either the device external storage or the application private directory beforehand. Sample code is as follows:
If you provide a path that is an external storage path outside of the application's specific directories, on Android 10 and above devices, you may face denial of access to the resource. This is due to Google introducing Partition Storage, a new storage management system. You can temporarily bypass this by adding the following code inside the <application> tag in the AndroidManifest.xml file: android:requestLegacyExternalStorage="true". This attribute only takes effect on applications with targetSdkVersion 29 (Android 10), and applications with a higher version targetSdkVersion are still recommended to use the application's private or external storage paths.
RTC Engine SDK 11.5 or later use the Content URI of the Content Provider component to play local music resources on Android devices.
On Android 11 and HarmonyOS 3.0 or later, if you cannot access resource files in the external storage directory, you need to request the MANAGE_EXTERNAL_STORAGE permission:
First, you need to add the following entry in your application's AndroidManifest file.