App Name
, Package Name
and Bundle ID
. Select Special 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.App Name
,Package Name
, and Bundle ID
according to your actual needs, select Player Premium, and click OK.dependencies {// The full feature version of SDK, including TRTC, live streaming, short video, player, and other featuresimplementation 'com.tencent.liteav:LiteAVSDK_Professional:latest.release'// Special Effect SDK example of S1-07 package is as followsimplementation 'com.tencent.mediacloud:TencentEffect_S1-07:latest.release'}
defaultConfig {ndk {abiFilters "armeabi-v7a", "arm64-v8a"}}
../assets/MotionRes
../assets/lut
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera.autofocus" />
android:hardwareAccelerated="false"
. Disabling hardware acceleration will result in failure to render the other party's video stream.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.-keep class com.tencent.** { *; }-keep class org.light.** { *;}-keep class org.libpag.** { *;}-keep class org.extra.** { *;}-keep class com.gyailib.**{ *;}-keep class androidx.exifinterface.** { *;}
import com.tencent.xmagic.telicense.TELicenseCheck;// If the purpose is just to trigger the download or update of the License, and not to care about the authentication result, then null is passed in for the fourth parameterTELicenseCheck.getInstance().setTELicense(context, URL, KEY, new TELicenseCheck.TELicenseCheckListener() {@Overridepublic void onLicenseCheckFinish(int errorCode, String msg) {// Note: This callback does not necessarily be called on the calling threadif (errorCode == TELicenseCheck.ERROR_OK) {// Authentication successful} else {// Authentication failed}}});
public class MApplication extends Application {public void onCreate() {super.onCreate();String licenceURL = ""; // The obtained licence URLString licenceKey = ""; // The obtained licence keyTXLiveBase.getInstance().setLicence(appContext, licenceURL, licenceKey);TXLiveBase.setListener(new TXLiveBaseListener() {@Overridepublic void onLicenceLoaded(int result, String reason) {Log.i(TAG, "onLicenceLoaded: result:" + result + ", reason:" + reason);if (result != 0) {// If the result is not 0, it means the setting has failed, and you need to retryTXLiveBase.getInstance().setLicence(appContext, licenceURL, licenceKey);}}});}}
TXLiveBase.getInstance().getLicenceInfo();
// Create TRTC SDK instance (single instance pattern)TRTCCloud mTRTCCloud = TRTCCloud.sharedInstance(context);// Set event listenersmTRTCCloud.addListener(trtcSdkListener);// Notifications from various SDK events (e.g., error codes, warning codes, audio and video status parameters, etc.)private TRTCCloudListener trtcSdkListener = new TRTCCloudListener() {@Overridepublic void onError(int errCode, String errMsg, Bundle extraInfo) {Log.d(TAG, errCode + errMsg);}@Overridepublic void onWarning(int warningCode, String warningMsg, Bundle extraInfo) {Log.d(TAG, warningCode + warningMsg);}};// Remove event listenermTRTCCloud.removeListener(trtcSdkListener);// Destroy TRTC SDK instance (single instance pattern)TRTCCloud.destroySharedInstance();
import com.tencent.xmagic.XmagicApi;// Initialize the beauty SDKXmagicApi mXmagicApi = new XmagicApi(context, XmagicResParser.getResPath(), new XmagicApi.OnXmagicPropertyErrorListener());// During development and debugging, you can set the log level to DEBUG. For release packages, set it to WARN to avoid impacting performancemXmagicApi.setXmagicLogLevel(Log.WARN);// Release the beauty SDK. This method needs to be called in the GL threadmXmagicApi.onDestroy();
// Set the SDK connection environment (if you serve global users, configure the SDK connection environment for global connection)TXLiveBase.setGlobalEnv("GDPR");// Create a Player objectTXVodPlayer mVodPlayer = new TXVodPlayer(mContext);// Add a View control for video renderingTXCloudVideoView mPlayerView = findViewById(R.id.video_view);// Associate the Player object with the View controlmVodPlayer.setPlayerView(mPlayerView);// Player parameter configurationTXVodPlayConfig config = new TXVodPlayConfig();config.setEnableAccurateSeek(true); // Set whether to seek accurately. The default value is trueconfig.setMaxCacheItems(5); // Set the number of cache files to 5config.setProgressInterval(200); // Set the interval for progress callbacks, in millisecondsconfig.setMaxBufferSize(50); // The maximum pre-load size, in MBmVodPlayer.setConfig(config);// Pass config to mVodPlayer// Player event listenermVodPlayer.setVodListener(new ITXVodPlayListener() {@Overridepublic void onPlayEvent(TXVodPlayer player, int event, Bundle param) {// Event notification}@Overridepublic void onNetStatus(TXVodPlayer player, Bundle bundle) {// Status feedback}});
// The TXCloudVideoView for video rendering needs to be added in advanceTXCloudVideoView mRenderView = findViewById(R.id.video_view);// Create a Player objectV2TXLivePlayer mLivePlayer = new V2TXLivePlayerImpl(mContext);// Associate the Player object with the video rendering viewmLivePlayer.setRenderView(mRenderView);// Player event listenermLivePlayer.setObserver(new V2TXLivePlayerObserver() {@Overridepublic void onVideoLoading(V2TXLivePlayer player, Bundle extraInfo) {// Video loading event}@Overridepublic void onVideoPlaying(V2TXLivePlayer player, boolean firstPlay, Bundle extraInfo) {// Video playback event}});
TXCloudVideoView
type. Therefore, you need to first define the view rendering control in the layout file.<com.tencent.rtmp.ui.TXCloudVideoViewandroid:id="@+id/live_cloud_view_main"android:layout_width="match_parent"android:layout_height="match_parent" />
TextureView
or SurfaceView
as the view rendering control, see Advanced Features - View Rendering Control.// Obtain the video rendering control for displaying the anchor's local video previewTXCloudVideoView mTxcvvAnchorPreviewView = findViewById(R.id.live_cloud_view_main);// Set video encoding parameters to determine the picture quality seen by remote usersTRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_960_540;encParam.videoFps = 15;encParam.videoBitrate = 1300;encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;mTRTCCloud.setVideoEncoderParam(encParam);// boolean mIsFrontCamera can specify using the front/rear camera for video capturemTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAnchorPreviewView);// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSICmTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
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.TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO; // Video mirror modeparams.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // Video fill modeparams.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // Video rotation angle// Set the rendering parameters for the local videomTRTCCloud.setLocalRenderParams(params);// Set the video mirror mode for the encoder outputmTRTCCloud.setVideoEncoderMirror(boolean mirror);// Set the rotation of the video encoder outputmTRTCCloud.setVideoEncoderRotation(int rotation);
public void enterRoomByAnchor(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// Take the room ID string as an exampleparams.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backendparams.userSig = getUserSig(userId);// Replace with your SDKAppIDparams.sdkAppId = SDKAppID;// Specify the anchor roleparams.role = TRTCCloudDef.TRTCRoleAnchor;// Enter the room in an interactive live streaming scenariomTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// Event callback for the result of entering the room@Overridepublic void onEnterRoom(long result) {if (result > 0) {// The result represents the time taken to join the room (in milliseconds)Log.d(TAG, "Enter room succeed");} else {// The result represents the error code fwhen you fail to enter the roomLog.d(TAG, "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.TRTC_APP_SCENE_LIVE
as the room entry mode.public void enterRoomByAudience(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// Take the room ID string as an exampleparams.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backendparams.userSig = getUserSig(userId);// Replace with your SDKAppIDparams.sdkAppId = SDKAppID;// Specify the audience roleparams.role = TRTCCloudDef.TRTCRoleAudience;// Enter the room in an interactive live streaming scenariomTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// Event callback for the result of entering the room@Overridepublic void onEnterRoom(long result) {if (result > 0) {// The result represents the time taken to join the room (in milliseconds)Log.d(TAG, "Enter room succeed");} else {// The result represents the error code fwhen you fail to enter the roomLog.d(TAG, "Enter room failed");}}
@Overridepublic void onUserAudioAvailable(String userId, boolean 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}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {// The remote user publishes/unpublishes the primary videoif (available) {// Subscribe to the remote user's video stream and bind the video rendering controlmTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, TXCloudVideoView view);} else {// Unsubscribe to the remote user's video stream and release the rendering controlmTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}
TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO; // Video mirror modeparams.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // Video fill modeparams.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // Video rotation angle// Set the rendering mode for the remote videomTRTCCloud.setRemoteRenderParams(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, params)
// Switch to the anchor rolemTRTCCloud.switchRole(TRTCCloudDef.TRTCRoleAnchor);// Event callback for switching role@Overridepublic void onSwitchRole(int errCode, String errMsg) {if (errCode == TXLiteAVCode.ERR_NULL) {// Role switched successfully}}
// Obtain the video rendering control for displaying the mic-connection audience's local video previewTXCloudVideoView mTxcvvAudiencePreviewView = findViewById(R.id.live_cloud_view_sub);// Set video encoding parameters to determine the picture quality seen by remote usersTRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_480_270;encParam.videoFps = 15;encParam.videoBitrate = 550;encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;mTRTCCloud.setVideoEncoderParam(encParam);// boolean mIsFrontCamera can specify using the front/rear camera for video capturemTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAudiencePreviewView);// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSICmTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
// Switch to the audience rolemTRTCCloud.switchRole(TRTCCloudDef.TRTCRoleAudience);// Event callback for switching role@Overridepublic void onSwitchRole(int errCode, String errMsg) {if (errCode == TXLiteAVCode.ERR_NULL) {// Stop camera capture and streamingmTRTCCloud.stopLocalPreview();// Stop microphone capture and streamingmTRTCCloud.stopLocalAudio();}}
public void exitRoom() {mTRTCCloud.stopLocalAudio();mTRTCCloud.stopLocalPreview();mTRTCCloud.exitRoom();}// Event callback for exiting the room@Overridepublic void onExitRoom(int reason) {if (reason == 0) {Log.d(TAG, "Actively call exitRoom to exit the room");} else if (reason == 1) {Log.d(TAG, "Removed from the current room by the server");} else if (reason == 2) {Log.d(TAG, "The current room has been dissolved");}}
onExitRoom
callback notification to inform you.enterRoom
again or switch to another audio and video SDK, wait for the onExitRoom
callback before proceeding. Otherwise, you may encounter various exceptional issues such as the camera, microphone device being forcibly occupied.DismissRoom
, as well as server dissolves string type room API DismissRoomByStrRoomId. You can call the server dissolves the room API to remove all users from the room and dissolve the room.TXCloudVideoView
type. Therefore, you need to first define the view rendering control in the layout file.<com.tencent.rtmp.ui.TXCloudVideoViewandroid:id="@+id/live_cloud_view_main"android:layout_width="match_parent"android:layout_height="match_parent" />
TextureView
or SurfaceView
as the view rendering control, see Advanced Features - View Rendering Control.// Obtain the video rendering control for displaying the anchor's local video previewTXCloudVideoView mTxcvvAnchorPreviewView = findViewById(R.id.live_cloud_view_main);// Set video encoding parameters to determine the picture quality seen by remote usersTRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_960_540;encParam.videoFps = 15;encParam.videoBitrate = 1300;encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;mTRTCCloud.setVideoEncoderParam(encParam);// boolean mIsFrontCamera can specify using the front/rear camera for video capturemTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAnchorPreviewView);// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSICmTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
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.TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO; // Video mirror modeparams.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // Video fill modeparams.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // Video rotation angle// Set the rendering parameters for the local videomTRTCCloud.setLocalRenderParams(params);// Set the video mirror mode for the encoder outputmTRTCCloud.setVideoEncoderMirror(boolean mirror);// Set the rotation of the video encoder outputmTRTCCloud.setVideoEncoderRotation(int rotation);
public void enterRoomByAnchor(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// Take the room ID string as an exampleparams.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backendparams.userSig = getUserSig(userId);// Replace with your SDKAppIDparams.sdkAppId = SDKAppID;// Specify the anchor roleparams.role = TRTCCloudDef.TRTCRoleAnchor;// Enter the room in an interactive live streaming scenariomTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// Event callback for the result of entering the room@Overridepublic void onEnterRoom(long result) {if (result > 0) {// The result represents the time taken to join the room (in milliseconds)Log.d(TAG, "Enter room succeed");} else {// The result represents the error code fwhen you fail to enter the roomLog.d(TAG, "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.TRTC_APP_SCENE_LIVE
as the room entry mode.public void startPublishMediaToCDN(String streamName) {// Set the expiration time for the push URLslong txTime = (System.currentTimeMillis() / 1000) + (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 URLsString secretParam = UrlHelper.getSafeUrl(LIVE_URL_KEY, streamName, txTime);// The target URLs for media stream publicationTRTCCloudDef.TRTCPublishTarget target = new TRTCCloudDef.TRTCPublishTarget();// The target URLs are set for relaying to CDNtarget.mode = TRTCCloudDef.TRTC_PublishBigStream_ToCdn;TRTCCloudDef.TRTCPublishCdnUrl cdnUrl = new TRTCCloudDef.TRTCPublishCdnUrl();// Construct push URLs (in RTMP format) to the live streaming service providercdnUrl.rtmpUrl = "rtmp://" + PUSH_DOMAIN + "/live/" + streamName + "?" + secretParam;// True means the cloud platform CSS, and false means third-party live streaming servicescdnUrl.isInternalLine = true;// Multiple CDN push URLs can be addedtarget.cdnUrlList.add(cdnUrl);// Set media stream encoding output parameters (can be defined according to business needs)TRTCCloudDef.TRTCStreamEncoderParam trtcStreamEncoderParam = new TRTCCloudDef.TRTCStreamEncoderParam();trtcStreamEncoderParam.audioEncodedChannelNum = 1;trtcStreamEncoderParam.audioEncodedKbps = 50;trtcStreamEncoderParam.audioEncodedCodecType = 0;trtcStreamEncoderParam.audioEncodedSampleRate = 48000;trtcStreamEncoderParam.videoEncodedFPS = 15;trtcStreamEncoderParam.videoEncodedGOP = 2;trtcStreamEncoderParam.videoEncodedKbps = 1300;trtcStreamEncoderParam.videoEncodedWidth = 540;trtcStreamEncoderParam.videoEncodedHeight = 960;// Start publishing media streammTRTCCloud.startPublishMediaStream(target, trtcStreamEncoderParam, null);}
KEY LIVE_URL_KEY
and push domain name PUSH_DOMAIN
can be obtained on the Domain Name Management page in the CSS Console.@Overridepublic void onStartPublishMediaStream(String taskId, int code, String message, Bundle 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}
// Set delay management mode (optional)mLivePlayer.setCacheParams(1.0f, 5.0f); // Auto modemLivePlayer.setCacheParams(1.0f, 1.0f); // Speed modemLivePlayer.setCacheParams(5.0f, 5.0f); // Smooth mode// Concatenate the pull URLs for playbackString flvURL = "http://" + PLAY_DOMAIN + "/live/" + streamName + ".flv"; // FLV URLString hlsURL = "http://" + PLAY_DOMAIN + "/live/" + streamName + ".m3u8"; // HLS URLString rtmpURL = "rtmp://" + PLAY_DOMAIN + "/live/" + streamName; // RTMP URLString webrtcURL = "webrtc://" + PLAY_DOMAIN + "/live/" + streamName; // WebRTC URL// Start playingmLivePlayer.startLivePlay(flvURL);// Custom set fill mode (optional)mLivePlayer.setRenderFillMode(V2TXLiveFillModeFit);// Customize video rendering direction (optional)mLivePlayer.setRenderRotation(V2TXLiveRotation0);
// Enter the TRTC room and start streamingpublic void enterRoom(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// Take the room ID string as an exampleparams.strRoomId = roomId;params.userId = userId;// UserSig obtained from the business backendparams.userSig = getUserSig(userId);// Replace with your SDKAppIDparams.sdkAppId = SDKAppID;// Specify the anchor roleparams.role = TRTCCloudDef.TRTCRoleAnchor;// Enable local audio and video capturestartLocalMedia();// In an interactive live streaming scenario, enter the room and push streamsmTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// Enable local video preview and audio capturepublic void startLocalMedia() {// Obtain the video rendering control for displaying the mic-connection audience's local video previewTXCloudVideoView mTxcvvAudiencePreviewView = findViewById(R.id.live_cloud_view_sub);// Set video encoding parameters to determine the picture quality seen by remote usersTRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_480_270;encParam.videoFps = 15;encParam.videoBitrate = 550;encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;mTRTCCloud.setVideoEncoderParam(encParam);// boolean mIsFrontCamera can specify using the front/rear camera for video capturemTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAudiencePreviewView);// Here you can specify the audio quality, from low to high as SPEECH/DEFAULT/MUSICmTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);}// Event callback for the result of entering the room@Overridepublic void onEnterRoom(long result) {if (result > 0) {// The result represents the time taken to join the room (in milliseconds)Log.d(TAG, "Enter room succeed");} else {// The result represents the error code fwhen you fail to enter the roomLog.d(TAG, "Enter room failed");}}
@Overridepublic void onUserAudioAvailable(String userId, boolean 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}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {// The remote user publishes/unpublishes the primary videoif (available) {// Subscribe to the remote user's video stream and bind the video rendering controlmTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, TXCloudVideoView view);} else {// Unsubscribe to the remote user's video stream and release the rendering controlmTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}@Overridepublic void onFirstVideoFrame(String userId, int streamType, int width, int height) {// The SDK starts rendering the first frame of the local or remote user's videoif (!userId.isEmpty()) {// Stop playing the CDN stream upon receiving the first frame of the anchor's videomLivePlayer.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@Overridepublic void onRemoteUserEnterRoom(String userId) {if (!mixUserList.contains(userId)) {mixUserList.add(userId);}updatePublishMediaToCDN(streamName, mixUserList, taskId);}// Event callback for updating the media stream@Overridepublic void onUpdatePublishMediaStream(String taskId, int code, String message, Bundle 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}// Update the publication of mixed media streams to the live streaming CDNpublic void updatePublishMediaToCDN(String streamName, List<String> mixUserList, String taskId) {// Set the expiration time for the push URLslong txTime = (System.currentTimeMillis() / 1000) + (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 URLsString secretParam = UrlHelper.getSafeUrl(LIVE_URL_KEY, streamName, txTime);// The target URLs for media stream publicationTRTCCloudDef.TRTCPublishTarget target = new TRTCCloudDef.TRTCPublishTarget();// The target URLs are set for relaying the mixed streams to CDNtarget.mode = TRTCCloudDef.TRTC_PublishMixStream_ToCdn;TRTCCloudDef.TRTCPublishCdnUrl cdnUrl = new TRTCCloudDef.TRTCPublishCdnUrl();// Construct push URLs (in RTMP format) to the live streaming service providercdnUrl.rtmpUrl = "rtmp://" + PUSH_DOMAIN + "/live/" + streamName + "?" + secretParam;// True means the cloud platform CSS, and false means third-party live streaming servicescdnUrl.isInternalLine = true;// Multiple CDN push URLs can be addedtarget.cdnUrlList.add(cdnUrl);// Set media stream encoding output parametersTRTCCloudDef.TRTCStreamEncoderParam trtcStreamEncoderParam = new TRTCCloudDef.TRTCStreamEncoderParam();trtcStreamEncoderParam.audioEncodedChannelNum = 1;trtcStreamEncoderParam.audioEncodedKbps = 50;trtcStreamEncoderParam.audioEncodedCodecType = 0;trtcStreamEncoderParam.audioEncodedSampleRate = 48000;trtcStreamEncoderParam.videoEncodedFPS = 15;trtcStreamEncoderParam.videoEncodedGOP = 2;trtcStreamEncoderParam.videoEncodedKbps = 1300;trtcStreamEncoderParam.videoEncodedWidth = 540;trtcStreamEncoderParam.videoEncodedHeight = 960;// Configuration parameters for media stream transcodingTRTCCloudDef.TRTCStreamMixingConfig trtcStreamMixingConfig = new TRTCCloudDef.TRTCStreamMixingConfig();if (mixUserList != null) {ArrayList<TRTCCloudDef.TRTCUser> audioMixUserList = new ArrayList<>();ArrayList<TRTCCloudDef.TRTCVideoLayout> videoLayoutList = new ArrayList<>();for (int i = 0; i < mixUserList.size() && i < 16; i++) {TRTCCloudDef.TRTCUser user = new TRTCCloudDef.TRTCUser();// The integer room number is intRoomIduser.strRoomId = mRoomId;user.userId = mixUserList.get(i);audioMixUserList.add(user);TRTCCloudDef.TRTCVideoLayout videoLayout = new TRTCCloudDef.TRTCVideoLayout();if (mixUserList.get(i).equals(mUserId)) {// The layout for the anchor's videovideoLayout.x = 0;videoLayout.y = 0;videoLayout.width = 540;videoLayout.height = 960;videoLayout.zOrder = 0;} else {// The layout for the mic-connection audience's videovideoLayout.x = 400;videoLayout.y = 5 + i * 245;videoLayout.width = 135;videoLayout.height = 240;videoLayout.zOrder = 1;}videoLayout.fixedVideoUser = user;videoLayout.fixedVideoStreamType = TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG;videoLayoutList.add(videoLayout);}// Specify the information for each input audio stream in the transcoding streamtrtcStreamMixingConfig.audioMixUserList = audioMixUserList;// Specify the information of position, size, layer, and stream type for each video screen in the mixed displaytrtcStreamMixingConfig.videoLayoutList = videoLayoutList;}// Update the published media streammTRTCCloud.updatePublishMediaStream(taskId, target, trtcStreamEncoderParam, trtcStreamMixingConfig);}
trtcStreamEncoderParam
and the stream name streamName
unchanged.// The reusable TRTC video rendering controlmLivePlayer.setRenderView(TXCloudVideoView view);// Restart playing CDN media streammLivePlayer.startLivePlay(URL);// Callback for player event listenermLivePlayer.setObserver(new V2TXLivePlayerObserver() {@Overridepublic void onVideoLoading(V2TXLivePlayer player, Bundle extraInfo) {// Video loading event}@Overridepublic void onVideoPlaying(V2TXLivePlayer player, boolean firstPlay, Bundle extraInfo) {// Video playback eventif (firstPlay) {mTRTCCloud.stopAllRemoteView();mTRTCCloud.stopLocalAudio();mTRTCCloud.stopLocalPreview();mTRTCCloud.exitRoom();}}});
onVideoPlaying
before exiting the TRTC room.// Event callback for the mic-connection audience's room exit@Overridepublic void onRemoteUserLeaveRoom(String userId, int reason) {if (mixUserList.contains(userId)) {mixUserList.remove(userId);}// The anchor updates the mixed stream taskupdatePublishMediaToCDN(streamName, mixUserList, taskId);}// Event callback for updating the media stream@Overridepublic void onUpdatePublishMediaStream(String taskId, int code, String message, Bundle 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}
public void exitRoom() {// Stop all published media streamsmTRTCCloud.stopPublishMediaStream("");mTRTCCloud.stopLocalAudio();mTRTCCloud.stopLocalPreview();mTRTCCloud.exitRoom();}// Event callback for stopping media streams@Overridepublic void onStopPublishMediaStream(String taskId, int code, String message, Bundle extraInfo) {// When you call 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@Overridepublic void onExitRoom(int reason) {if (reason == 0) {Log.d(TAG, "Actively call exitRoom to exit the room");} else if (reason == 1) {Log.d(TAG, "Removed from the current room by the server");} else if (reason == 2) {Log.d(TAG, "The current room has been dissolved");}}
taskId
. This will stop all the media streams you have published.onExitRoom
callback notification to inform you.// Construct product pop-up message bodyJSONObject jsonObject = new JSONObject();try {jsonObject.put("cmd", "item_popup_msg");JSONObject msgJsonObject = new JSONObject();msgJsonObject.put("itemNumber", 1); // Item numbermsgJsonObject.put("itemPrice", 199.0); // Item pricemsgJsonObject.put("itemTitle", "xxx"); // Item titlemsgJsonObject.put("itemUrl", "xxx");// Item URLjsonObject.put("msg", msgJsonObject);} catch (JSONException e) {e.printStackTrace();}String data = jsonObject.toString();// Send custom group messages (it is recommended that product pop-up messages should be set to high priority)V2TIMManager.getInstance().sendGroupCustomMessage(data.getBytes(), mRoomId,V2TIMMessage.V2TIM_PRIORITY_HIGH, new V2TIMValueCallback<V2TIMMessage>() {@Overridepublic void onError(int i, String s) {// Failed to send product pop-up message}@Overridepublic void onSuccess(V2TIMMessage v2TIMMessage) {// Successfully sent product pop-up message// Locally rendering of product pop-up effect}});
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. It is recommended to set product pop-up messages to high priority"MsgBody": [{"MsgType": "TIMCustomElem","MsgContent": {// itemNumber: item number; itemPrice: item price; itemTitle: item title; itemUrl: item URL"Data": "{\\"cmd\\": \\"item_popup_msg\\", \\"msg\\": {\\"itemNumber\\": 1, \\"itemPrice\\": 199.0, \\"itemTitle\\": \\"xxx\\", \\"itemUrl\\": \\"xxx\\"}}"}}]}
// Custom group messages receivedV2TIMManager.getInstance().addSimpleMsgListener(new V2TIMSimpleMsgListener() {@Overridepublic void onRecvGroupCustomMessage(String msgID, String groupID, V2TIMGroupMemberInfo sender, byte[] customData) {String customStr = new String(customData);if (!customStr.isEmpty()) {try {JSONObject jsonObject = new JSONObject(customStr);String command = jsonObject.getString("cmd");JSONObject messageJsonObject = jsonObject.getJSONObject("msg");if (command.equals("item_popup_msg")) {int itemNumber = messageJsonObject.getInt("itemNumber"); // Item numberdouble itemPrice = messageJsonObject.getDouble("itemPrice"); // Item priceString itemTitle = messageJsonObject.getString("itemTitle"); // Item titleString itemUrl = messageJsonObject.getString("itemUrl"); // Item URL// Render product pop-up effect based on item number, item price, item title, and item URL}} catch (JSONException e) {e.printStackTrace();}}}});
// Construct product pop-up message bodyJSONObject jsonObject = new JSONObject();try {jsonObject.put("cmd", "item_popup_msg");JSONObject msgJsonObject = new JSONObject();msgJsonObject.put("itemNumber", 1); // Item numbermsgJsonObject.put("itemPrice", 199.0); // Item pricemsgJsonObject.put("itemTitle", "xxx"); // Item titlemsgJsonObject.put("itemUrl", "xxx");// Item URLjsonObject.put("msg", msgJsonObject);} catch (JSONException e) {e.printStackTrace();}String data = jsonObject.toString();// Send SEI informationmTRTCCloud.sendSEIMsg(data.getBytes(), 1);
mTRTCCloud.setListener(new TRTCCloudListener() {@Overridepublic void onRecvSEIMsg(String userId, byte[] data) {String dataStr = new String(data);if (!dataStr.isEmpty()) {try {JSONObject jsonObject = new JSONObject(dataStr);String command = jsonObject.getString("cmd");JSONObject messageJsonObject = jsonObject.getJSONObject("msg");if (command.equals("item_popup_msg")) {int itemNumber = messageJsonObject.getInt("itemNumber"); // Item numberdouble itemPrice = messageJsonObject.getDouble("itemPrice"); // Item priceString itemTitle = messageJsonObject.getString("itemTitle"); // Item titleString itemUrl = messageJsonObject.getString("itemUrl"); // Item URL// Render product pop-up effect based on item number, item price, item title, and item URL}} catch (JSONException e) {e.printStackTrace();}}}});
// Set the PayloadType for sending SEI messages in TRTCmTRTCCloud.callExperimentalAPI("{\\"api\\":\\"setSEIPayloadType\\",\\"params\\":{\\"payloadType\\":5}}");// Enable receiving SEI messages on the player and set the PayloadTypemLivePlayer.enableReceiveSeiMessage(true, 5);// SEI message callback and parsingmLivePlayer.setObserver(new V2TXLivePlayerObserver() {@Overridepublic void onReceiveSeiMessage(V2TXLivePlayer player, int payloadType, byte[] data) {String dataStr = new String(data);if (!dataStr.isEmpty()) {try {JSONObject jsonObject = new JSONObject(dataStr);String command = jsonObject.getString("cmd");JSONObject messageJsonObject = jsonObject.getJSONObject("msg");if (command.equals("item_popup_msg")) {int itemNumber = messageJsonObject.getInt("itemNumber"); // Item numberdouble itemPrice = messageJsonObject.getDouble("itemPrice"); // Item priceString itemTitle = messageJsonObject.getString("itemTitle"); // Item titleString itemUrl = messageJsonObject.getString("itemUrl"); // Item URL// Render product pop-up effect based on item number, item price, item title, and item URL}} catch (JSONException e) {e.printStackTrace();}}}});
PayloadType
of the TRTC sender and the player receiver are consistent, so that the audience can successfully receive the SEI messages relayed via TRTC.// Play URL video resourceString url = "http://1252463788.vod2.myqcloud.com/xxxxx/v.f20.mp4";mVodPlayer.startVodPlay(url);// Play local video resourcesString localFile = "/sdcard/video.mp4";mVodPlayer.startVodPlay(localFile);
// Recommended to use the new API below// The psign means player signature. For more information about the signature and how to generate it, see: https://www.tencentcloud.com/document/product/266/42436?from_cn_redirect=1TXPlayInfoParams playInfoParam = new TXPlayInfoParams(1252463788, // The appId of the cloud platform account"4564972819220421305", // The fileId of video"psignxxxxxxx"); // Player signaturemVodPlayer.startVodPlay(playInfoParam);// Old API, not recommendedTXPlayerAuthBuilder authBuilder = new TXPlayerAuthBuilder();authBuilder.setAppId(1252463788);authBuilder.setFileId("4564972819220421305");mVodPlayer.startVodPlay(authBuilder);
// Adjust the progress (seconds)mVodPlayer.seek(time);// Pause playbackmVodPlayer.pause();// Resume playbackmVodPlayer.resume();// End playback (clear the last frame)mVodPlayer.stopPlay(true);
startVodPlay
. Otherwise, it will cause a large amount of memory leak and screen flash.onDestroy()
function. Otherwise, it may cause memory leaks and a "Receiver not registered" warning.@Overridepublic void onDestroy() {super.onDestroy();mVodPlayer.stopPlay(true); // True means clearing the last framemPlayerView.onDestroy();}
public void connectOtherRoom(String roomId, String userId) {try {JSONObject jsonObj = new JSONObject();// The digit room number is roomIdjsonObj.put("strRoomId", roomId);jsonObj.put("userId", userId);mTRTCCloud.ConnectOtherRoom(jsonObj.toString());} catch (JSONException e) {e.printStackTrace();}}// Result callback for requesting cross-room mic-connection@Overridepublic void onConnectOtherRoom(String userId, int errCode, String 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}
ConnectOtherRoom()
multiple times. Currently, a room can connect with up to three other room anchors at most, and up to 10 anchors in a room can conduct cross-room mic-connection competition with anchors in other rooms.@Overridepublic void onUserAudioAvailable(String userId, boolean 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}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {// The remote user publishes/unpublishes the primary videoif (available) {// Subscribe to the remote user's video stream and bind the video rendering controlmTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, TXCloudVideoView view);} else {// Unsubscribe to the remote user's video stream and release the rendering controlmTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}
// Exiting cross-room mic-connectionmTRTCCloud.DisconnectOtherRoom();// Result callback for exiting cross-room mic-connection@Overridepublic void onDisConnectOtherRoom(int errCode, String errMsg) {super.onDisConnectOtherRoom(errCode, errMsg);}
DisconnectOtherRoom()
, you may exit the cross-room mic-connection PK with all other room anchors.DisconnectOtherRoom()
to exit the cross-room mic-connection PK.XmagicResParser.setResPath(new File(getFilesDir(), "xmagic").getAbsolutePath());//loading// Copy resource files to the private directory. Only need to do it onceXmagicResParser.copyRes(getApplicationContext());
XmagicResParser.setResPath (local path of the downloaded resource file);
mTRTCCloud.setLocalVideoProcessListener(TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE, new TRTCCloudListener.TRTCVideoFrameListener() {@Overridepublic void onGLContextCreated() {// The OpenGL environment has already been set up internally within the SDK. At this point, the initialization of third-party beauty features can be doneif (mXmagicApi == null) {XmagicApi mXmagicApi = new XmagicApi(context, XmagicResParser.getResPath(), new XmagicApi.OnXmagicPropertyErrorListener());} else {mXmagicApi.onResume();}}@Overridepublic int onProcessVideoFrame(TRTCCloudDef.TRTCVideoFrame srcFrame, TRTCCloudDef.TRTCVideoFrame dstFrame) {// Callback for integrating with third-party beauty components for video processingif (mXmagicApi != null) {dstFrame.texture.textureId = mXmagicApi.process(srcFrame.texture.textureId, srcFrame.width, srcFrame.height);}return 0;}@Overridepublic void onGLContextDestory() {// The internal OpenGL environment within the SDK has been terminated. At this point, proceed to clean up resources for third-party beauty featuresmXmagicApi.onDestroy();}});
public void enableDualStreamMode(boolean enable) {// Video encoding parameters for the small stream (customizable).TRTCCloudDef.TRTCVideoEncParam smallVideoEncParam = new TRTCCloudDef.TRTCVideoEncParam();smallVideoEncParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_480_270;smallVideoEncParam.videoFps = 15;smallVideoEncParam.videoBitrate = 550;smallVideoEncParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;mTRTCCloud.enableEncSmallVideoStream(enable, smallVideoEncParam);}
// Optional video stream types when you subscribe to a remote user's video streammTRTCCloud.startRemoteView(userId, streamType, videoView);// You can switch the size of the specified remote user's screen at any timemTRTCCloud.setRemoteVideoStreamType(userId, streamType);
TRTC_VIDEO_STREAM_TYPE_SMALL
with streamType
to pull a low-quality small video for viewing.TXCloudVideoView
is used as the video rendering control, and both SurfaceView
and TextureView
rendering schemes are supported. Below are the methods for specifying the type of rendering control and updating the video rendering control.TXCloudVideoView
, you can code as follows.// Mandatory use ofTextureView
TextureView textureView = findViewById(R.id.texture_view);TXCloudVideoView cloudVideoView = new TXCloudVideoView(context);cloudVideoView.addVideoView(textureView);// Mandatory use ofSurfaceView
SurfaceView surfaceView = findViewById(R.id.surface_view);TXCloudVideoView cloudVideoView = new TXCloudVideoView(surfaceView);
// Update local preview screen rendering controlmTRTCCloud.updateLocalView(videoView);// Update the remote user's video rendering controlmTRTCCloud.updateRemoteView(userId, streamType, videoView);
videoView
refers to the target video rendering control. And streamType
only supports TRTC_VIDEO_STREAM_TYPE_BIG
and TRTC_VIDEO_STREAM_TYPE_SUB
.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. Nnote 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 was denied. Check if enterRoom is called consecutively to enter rooms with the same ID. |
Enumeration | Value | Description |
ERR_CAMERA_START_FAIL | -1301 | Failed to enable the camera. For example, if there is an exception for the camera's configuration program (driver) on a Windows or Mac 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 camera's configuration program (driver) on a Windows or Mac 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 separately affect the mirror effect of the local preview and the video encoding output (the mirror mode for 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 videoTRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_ENABLE; // Video mirror modeparams.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // Video fill modeparams.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // Video rotation anglemTRTCCloud.setLocalRenderParams(params);// Set the video mirror mode for the encoder outputmTRTCCloud.setVideoEncoderMirror(true);
// Get the maximum zoom factor for the camera (only for mobile devices)float zoomRatio = mTRTCCloud.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-in lens). The maximum recommended value is 5. Exceeding this may result in blurry video.mTRTCCloud.getDeviceManager().setCameraZoomRatio(zoomRatio);
// Enable or disable the camera's autofocus feature (only for mobile devices)mTRTCCloud.getDeviceManager().enableCameraAutoFocus(false);// 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 enableCameraAutoFocusmTRTCCloud.getDeviceManager().setCameraFocusPosition(int x, int y);
// Determine if the current camera is the front camera (only for mobile devices)boolean isFrontCamera = mTRTCCloud.getDeviceManager().isFrontCamera();// Switch to front or rear cameras (only for mobile devices)// Passing true means switching to front, and passing false means switching to rearmTRTCCloud.getDeviceManager().switchCamera(!isFrontCamera);
Was this page helpful?