Overview of Scenario-Based Solutions
소셜 엔터테인먼트
이커머스 라이브 방송
Audio/Video Call
원거리 실시간 조작
스마트 고객 서비스
AI 인터뷰









App Name, Package Name, Bundle Id를 입력하고 플레이어 고급판을 선택한 후 생성를 클릭하세요.

dependencies {// 전체 기능판 SDK에 RTC Engine, 라이브 방송, 쇼트 비디오, 플레이어 등 다양한 기능 포함됩니다implementation 'com.tencent.liteav:LiteAVSDK_Professional:latest.release'// 뷰티 AR SDK 예: S1-07 패키지는 다음과 같습니다implementation '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"를 설정하지 마십시오. 하드웨어 가속을 끄면 상대방의 비디오 스트림이 렌더링되지 않습니다.targetSdkVersion이 31이거나 대상 기기가 Android 12및 그 이상 시스템 버전과 관련된 경우, 블루투스 기능을 정상적으로 사용하기 위해 코드에서 android.permission.BLUETOOTH_CONNECT 권한을 동적으로 신청해야 합니다. 자세한 내용은 블루투스 권한를 참조하십시오.-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;// 라이선스dml 다운로드 또는 업데이트만을 목적으로 하고 인증 결과에 관심이 없는 경우, 네 번째 매개변수에 null을 전달합니다.TELicenseCheck.getInstance().setTELicense(context, URL, KEY, new TELicenseCheck.TELicenseCheckListener() {@Overridepublic void onLicenseCheckFinish(int errorCode, String msg) {// 주의: 이 콜백은 호출 스레드에서 실행되지 않을 수 있습니다if (errorCode == TELicenseCheck.ERROR_OK) {// 인증 성공} else {// 인증 실패}}});
public class MApplication extends Application {public void onCreate() {super.onCreate();String licenceURL = ""; // 가져온 licence urlString licenceKey = ""; // 가져온 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) {// result가 0이 아니면 설정 실패를 의미하며, 재시도가 필요합니다.TXLiveBase.getInstance().setLicence(appContext, licenceURL, licenceKey);}}});}}
TXLiveBase.getInstance().getLicenceInfo();
// RTC Engine SDK 인스턴스의 생성(싱글톤 모드)TRTCCloud mTRTCCloud = TRTCCloud.sharedInstance(context);// 이벤트 리스너의 설정mTRTCCloud.addListener(trtcSdkListener);// SDK의 다양한 이벤트 알림(예: 오류 코드, 경고 코드, 오디오/비디오 상태 매개변수 등)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);}};// 이벤트 리스너의 제거mTRTCCloud.removeListener(trtcSdkListener);// RTC Engine SDK 인스턴스(싱글톤 모드)를 파기합니다.TRTCCloud.destroySharedInstance();
import com.tencent.xmagic.XmagicApi;// 뷰티 AR SDK의 초기화XmagicApi mXmagicApi = new XmagicApi(context, XmagicResParser.getResPath(), new XmagicApi.OnXmagicPropertyErrorListener());// 개발 및 디버깅 시 로그 등급을 DEBUG로 설정하며 릴리스 패키지는 WARN으로 설정하세요. 그렇지 않으면 성능에 영향을 미칠 수 있습니다.mXmagicApi.setXmagicLogLevel(Log.WARN);// 뷰티 AR SDK를 릴리스합니다. 이 방법은 GL 스레드에서 호출되어야 합니다.mXmagicApi.onDestroy();
// SDK 접근 환경을 설정합니다(글로벌 사용자를 대상으로 하는 경우 SDK 접근 환경을 글로벌 접근 환경으로 구성하세요)TXLiveBase.setGlobalEnv("GDPR");// Player 객체의 생성TXVodPlayer mVodPlayer = new TXVodPlayer(mContext);// 비디오 렌더링을 위한 View 컨트롤을 추가합니다TXCloudVideoView mPlayerView = findViewById(R.id.video_view);// Player 객체와 View 컨트롤의 연결mVodPlayer.setPlayerView(mPlayerView);// 플레이어 매개변수의 구성TXVodPlayConfig config = new TXVodPlayConfig();config.setEnableAccurateSeek(true); // seek의 설정이 정확한지?,기본값이 true입니다config.setMaxCacheItems(5); // 캐시 파일 개수를 5로 설정합니다config.setProgressInterval(200); // 진행 콜백 간격을 설정합니다. 단위는 밀리초입니다config.setMaxBufferSize(50); // 최대 사전 로드 크기의 단위는 Mb입니다mVodPlayer.setConfig(config); // config를 mVodPlayer에 전달합니다// 플레이어 이벤트의 리스너mVodPlayer.setVodListener(new ITXVodPlayListener() {@Overridepublic void onPlayEvent(TXVodPlayer player, int event, Bundle param) {// 이벤트 알림}@Overridepublic void onNetStatus(TXVodPlayer player, Bundle bundle) {// 상태 피드백}});
// 비디오 렌더링을 위한 TXCloudVideoView를 미리서 추가해야 합니다TXCloudVideoView mRenderView = findViewById(R.id.video_view);// Player 객체의 생성V2TXLivePlayer mLivePlayer = new V2TXLivePlayerImpl(mContext);// Player 객체및 비디오 렌더링 view와 관련mLivePlayer.setRenderView(mRenderView);// 플레이어 이벤트의 리스너mLivePlayer.setObserver(new V2TXLivePlayerObserver() {@Overridepublic void onVideoLoading(V2TXLivePlayer player, Bundle extraInfo) {// 비디오 로드 이벤트}@Overridepublic void onVideoPlaying(V2TXLivePlayer player, boolean firstPlay, Bundle extraInfo) {// 비디오 재생 이벤트}});
TXCloudVideoView 유형만 전달할 수 있으므로, 먼저 레이아웃 파일에 뷰 렌더링 컨트롤을 정의해야 합니다.<com.tencent.rtmp.ui.TXCloudVideoViewandroid:id="@+id/live_cloud_view_main"android:layout_width="match_parent"android:layout_height="match_parent" />
// 스트리머의 로컬 화면 미리보기를 표시하기 위한 비디오 렌더링 컨트롤을 가져옵니다TXCloudVideoView mTxcvvAnchorPreviewView = findViewById(R.id.live_cloud_view_main);// 원격 사용자가 보는 화면 품질을 결정하는 비디오 인코딩 매개변수를 설정합니다.TRTCCloudDef.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는 전면/후면 카메라의 사용을 지정하여 비디오를 수집합니다.mTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAnchorPreviewView);// 여기서는 음질을 지정할 수 있으며, 낮음에서 높음 순으로 SPEECH/DEFAULT/MUSIC입니다.mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
enterRoom 전에 위 인터페이스를 호출하면 SDK는 카메라 미리보기와 오디오 수집만 시작하며, enterRoom을 호출한 후에야 스트리밍을 시작합니다.enterRoom 후에 위 인터페이스를 호출하면 SDK는 카메라 미리보기와 오디오 수집을 시작하고 자동으로 스트리밍을 시작합니다.TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO; // 화면 미러 모드params.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // 화면 채우기 모드params.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // 화면 회전 각도// 로컬 화면의 렌더링 매개변수를 설정합니다mTRTCCloud.setLocalRenderParams(params);// 인코더 출력 화면 미러 모드를 설정합니다mTRTCCloud.setVideoEncoderMirror(boolean mirror);// 비디오 인코더 출력 화면의 방향을 설정합니다mTRTCCloud.setVideoEncoderRotation(int rotation);
public void enterRoomByAnchor(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// 문자열 방 번호를 예로 들면params.strRoomId = roomId;params.userId = userId;// 업무 백엔드에서 가져온 UserSigparams.userSig = getUserSig(userId);// 손님의 SDKAppID로 교체합니다params.sdkAppId = SDKAppID;// 스트리머 역할의 지정params.role = TRTCCloudDef.TRTCRoleAnchor;// 인터랙티브 라이브 방송 시나리오로 방 입장하기mTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// 방 입장 결과 이벤트의 콜백@Overridepublic void onEnterRoom(long result) {if (result > 0) {// result는 방에 임장하는 데 소요된 시간(밀리초)을 나타냅니다.Log.d(TAG, "Enter room succeed");} else {// result는 방 입장 실패의 오류 코드를 나타냅니다.Log.d(TAG, "Enter room failed");}}
roomId과 문자열 유형 strRoomId으로 구분되며, 두 유형의 방은 서로 통하지 않으므로 방 번호 유형을 통일기키는 것이 좋습니다.TRTC_APP_SCENE_LIVE으로 선택하는 것이 좋습니다.public void enterRoomByAudience(String roomId, String userId) {TRTCCloudDef.TRTCParams params = new TRTCCloudDef.TRTCParams();// 문자열 방 번호를 예로 들면params.strRoomId = roomId;params.userId = userId;// 업무 백엔드에서 가져온 UserSigparams.userSig = getUserSig(userId);// 손님의 SDKAppID로 교체합니다params.sdkAppId = SDKAppID;// 시청자 역할의 지정params.role = TRTCCloudDef.TRTCRoleAudience;// 인터랙티브 라이브 방송 시나리오로 방 입장하기mTRTCCloud.enterRoom(params, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}// 방 입장 결과 이벤트의 콜백@Overridepublic void onEnterRoom(long result) {if (result > 0) {// result는 방에 입장하는 데 소요된 시간(밀리초)을 나타냅니다.Log.d(TAG, "Enter room succeed");} else {// result는 방 입장 실패의 오류 코드를 나타냅니다.Log.d(TAG, "Enter room failed");}}
@Overridepublic void onUserAudioAvailable(String userId, boolean available) {// 원격 사용자가 자신의 오디오를 게시/취소합니다// 자동 구독 모드에서 사용자가 아무런 작업을 하지 않아도 SDK가 원격 사용자의 오디오를 자동으로 재생합니다.}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {// 원격 사용자가 메인 비디오 화면을 게시/취소합니다if (available) {// 원격 사용자의 비디오 스트림을 구독하고 비디오 렌더링 컨트롤을 바인딩합니다mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, TXCloudVideoView view);} else {// 원격 사용자의 비디오 스트림 구독을 중지하고 렌더링 컨트롤을 릴리스합니다mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}
TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO; // 화면 미러 모드params.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // 화면 채우기 모드params.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // 화면 회전 각도// 원격 화면의 렌더링 모드를 설정합니다mTRTCCloud.setRemoteRenderParams(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, params)
// 스트리머 역할로 전환됩니다.mTRTCCloud.switchRole(TRTCCloudDef.TRTCRoleAnchor);// 역할 전환 이벤트의 콜백@Overridepublic void onSwitchRole(int errCode, String errMsg) {if (errCode == TXLiteAVCode.ERR_NULL) {// 역할 전환 성공}}
// 연결된 시청자의 로컬 화면 미리보기를 표시하기 위한 비디오 렌더링 컨트롤을 가져옵니다.TXCloudVideoView mTxcvvAudiencePreviewView = findViewById(R.id.live_cloud_view_sub);// 원격 사용자가 보는 화면 품질을 결정하는 비디오 인코딩 매개변수를 설정합니다.TRTCCloudDef.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는 전면/후면 카메라의 사용을 지정하여 비디오를 수집합니다.mTRTCCloud.startLocalPreview(mIsFrontCamera, mTxcvvAudiencePreviewView);// 여기서는 음질을 지정할 수 있으며, 낮음에서 높음 순으로 SPEECH/DEFAULT/MUSIC입니다.mTRTCCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
// 시청자 역할로 전환됩니다mTRTCCloud.switchRole(TRTCCloudDef.TRTCRoleAudience);// 역할 전환 이벤트의 콜백@Overridepublic void onSwitchRole(int errCode, String errMsg) {if (errCode == TXLiteAVCode.ERR_NULL) {// 카메라 수집 및 스트리밍 중지합니다mTRTCCloud.stopLocalPreview();// 마이크 수집 및 스트리밍 중지합니다mTRTCCloud.stopLocalAudio();}}
public void exitRoom() {mTRTCCloud.stopLocalAudio();mTRTCCloud.stopLocalPreview();mTRTCCloud.exitRoom();}// 방 나가기 이벤트의 콜백@Overridepublic void onExitRoom(int reason) {if (reason == 0) {Log.d(TAG, "exitRoom을 호출하여 방에서 나가기");} else if (reason == 1) {Log.d(TAG, "서버에 의해 현재 방에서 나가게 됩니다");} else if (reason == 2) {Log.d(TAG, "현재 방 전체가 해체됩니다");}}
onExitRoom 콜백을 통해 알려줍니다.enterRoom을 다시 호출하거나 다른 음성/영상 SDK로 전환하려면 onExitRoom 콜백이 발생한 후 관련 작업을 수행하십시오. 그렇지 않으면 카메라나 마이크 장치에서 점유됨 등 다양한 오류 문제가 발생할 수 있습니다.DismissRoom과 문자열 유형 방을 해산하는 API DismissRoomByStrRoomId를 제공합니다. 서버 측의 방 해산 인터페이스를 호출하여 방 내 모든 사용자를 방에서 나가게 시키고 방을 해산할 수 있습니다.// 상품 팝업 메시지 본문의 구성JSONObject jsonObject = new JSONObject();try {jsonObject.put("cmd", "item_popup_msg");JSONObject msgJsonObject = new JSONObject();msgJsonObject.put("itemNumber", 1); // 상품 번호msgJsonObject.put("itemPrice", 199.0); // 상품 가격msgJsonObject.put("itemTitle", "xxx"); // 상품 제목msgJsonObject.put("itemUrl", "xxx"); // 상품 이미지 주소jsonObject.put("msg", msgJsonObject);} catch (JSONException e) {e.printStackTrace();}String data = jsonObject.toString();// 그룹 커스텀 메시지의 전송 (상품 팝업 메시지는 높은 우선순위로 설정하는 것이 좋음)V2TIMManager.getInstance().sendGroupCustomMessage(data.getBytes(), mRoomId,V2TIMMessage.V2TIM_PRIORITY_HIGH, new V2TIMValueCallback<V2TIMMessage>() {@Overridepublic void onError(int i, String s) {// 상품 팝업 메시지의 전송이 실패됩니다}@Overridepublic void onSuccess(V2TIMMessage v2TIMMessage) {// 상품 팝업 메시지의 전송이 성공됩니다// 로컬에서 상품 팝업 효과를 렌더링합니다}});
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", // 메시지의 우선순위에서 상품 팝업 메시지는 높은 우선순위로 설정하는 것을 권장합니다"MsgBody": [{"MsgType": "TIMCustomElem","MsgContent": {// itemNumber: 상품 번호; itemPrice: 상품 가격; itemTitel: 상품 제목; itemUrl: 상품 이미지 주소"Data": "{\\"cmd\\": \\"item_popup_msg\\", \\"msg\\": {\\"itemNumber\\": 1, \\"itemPrice\\": 199.0, \\"itemTitle\\": \\"xxx\\", \\"itemUrl\\": \\"xxx\\"}}"}}]}
// 그룹 커스텀 메시지의 수신V2TIMManager.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"); // 상품 번호double itemPrice = messageJsonObject.getDouble("itemPrice"); // 상품 가격String itemTitle = messageJsonObject.getString("itemTitle"); // 상품 제목String itemUrl = messageJsonObject.getString("itemUrl"); // 상품 이미지 주소// 상품 번호, 상품 가격, 상품 제목, 상품 이미지 주소에 따라 상품 팝업 효과를 렌더링합니다}} catch (JSONException e) {e.printStackTrace();}}}});
// 상품 팝업 메시지 본문의 구성JSONObject jsonObject = new JSONObject();try {jsonObject.put("cmd", "item_popup_msg");JSONObject msgJsonObject = new JSONObject();msgJsonObject.put("itemNumber", 1); // 상품 번호msgJsonObject.put("itemPrice", 199.0); // 상품 가격msgJsonObject.put("itemTitle", "xxx"); // 상품 제목msgJsonObject.put("itemUrl", "xxx"); // 상품 이미지 주소jsonObject.put("msg", msgJsonObject);} catch (JSONException e) {e.printStackTrace();}String data = jsonObject.toString();// SEI 정보의 전송mTRTCCloud.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"); // 상품 번호double itemPrice = messageJsonObject.getDouble("itemPrice"); // 상품 가격String itemTitle = messageJsonObject.getString("itemTitle"); // 상품 제목String itemUrl = messageJsonObject.getString("itemUrl"); // 상품 이미지 주소// 상품 번호, 상품 가격, 상품 제목, 상품 이미지 주소에 따라 상품 팝업 효과를 렌더링합니다}} catch (JSONException e) {e.printStackTrace();}}}});
// URL 비디오 리소스의 재생String url = "http://1252463788.vod2.myqcloud.com/xxxxx/v.f20.mp4";mVodPlayer.startVodPlay(url);// 로컬 비디오 리소스의 재생String localFile = "/sdcard/video.mp4";mVodPlayer.startVodPlay(localFile);
// 아래의 새 인터페이스 사용을 권장합니다// psign은 플레이어 서명이고 서명 소개 및 생성 방법은 다음 링크를 참조하세요. https://www.tencentcloud.com/document/product/266/42436?from_cn_redirect=1TXPlayInfoParams playInfoParam = new TXPlayInfoParams(1252463788, // 텐센트 클라우드 계정의 appId"4564972819220421305", // 비디오의 fileId"psignxxxxxxx"); // 플레이어 서명mVodPlayer.startVodPlay(playInfoParam);// 구 인터페이스이고 사용을 권장하지 않습니다TXPlayerAuthBuilder authBuilder = new TXPlayerAuthBuilder();authBuilder.setAppId(1252463788);authBuilder.setFileId("4564972819220421305");mVodPlayer.startVodPlay(authBuilder);
// 진행률 조정(초)mVodPlayer.seek(time);// 재생 일시 정지mVodPlayer.pause();// 재생 재개mVodPlayer.resume();// 재생 종료(마지막 프레임 화면를 제거합니다)mVodPlayer.stopPlay(true);
startVodPlay 전에 View 컨트롤을 반드시 파기해야 합니다. 그렇지 않으면 메모리 누수 및 화면 깜빡임 문제가 발생할 수 있습니다.onDestroy() 함수를 반드시 호출해야 합니다. 그렇지 않으면 메모리 누출 및 "Receiver not registered" 경고가 발생할 수 있습니다.@Overridepublic void onDestroy() {super.onDestroy();mVodPlayer.stopPlay(true); // true는 마지막 프레임을 제거하는 것을 의미합니다mPlayerView.onDestroy();}
public void connectOtherRoom(String roomId, String userId) {try {JSONObject jsonObj = new JSONObject();// 숫자 방 번호는 roomId입니다jsonObj.put("strRoomId", roomId);jsonObj.put("userId", userId);mTRTCCloud.ConnectOtherRoom(jsonObj.toString());} catch (JSONException e) {e.printStackTrace();}}// 크로스 룸 연결 결과의 콜백@Overridepublic void onConnectOtherRoom(String userId, int errCode, String errMsg) {// 크로스 룸 연결을 하려는 다른 방 스트리머의 사용자 ID// 에러 코드, ERR_NULL은 요청 성공을 나타냅니다// 에러 정보}
ConnectOtherRoom()을 여러 번 호출하여 여러 방의 스트리머와 크로스 룸 연결을 구현할 수 있습니다. 현재에 한 방은 최대 세 개의 다른 방의 스트리머와의 크로스 룸 연결이 가능하며, 한 방 내에서 최대 10명의 스트리머가 다른 방의 스크리머와 크로스 룸 연결을 할 수 있습니다.@Overridepublic void onUserAudioAvailable(String userId, boolean available) {// 원격 사용자가 자신의 오디오를 게시/취소합니다// 자동 구독 모드에서는 사용자가 아무런 작업을 하지 않아도 SDK가 원격 사용자의 오디오를 자동으로 재생합니다.}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {// 원격 사용자가 메인 비디오 화면을 게시/취소합니다if (available) {// 원격 사용자의 비디오 스트림을 구독하고 비디오 렌더링 컨트롤을 바인딩합니다mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, TXCloudVideoView view);} else {// 원격 사용자의 비디오 스트림 구독을 중지하고 렌더링 컨트롤을 릴리스합니다mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}
// 크로스 룸 연결의 종료mTRTCCloud.DisconnectOtherRoom();// 크로스 룸 연결 종료 결과의 콜백@Overridepublic void onDisConnectOtherRoom(int errCode, String errMsg) {super.onDisConnectOtherRoom(errCode, errMsg);}
DisconnectOtherRoom()을 호출하면 모든 다른 방의 스트리머와의 크로스 룸 PK 연결이 종료됩니다.DisconnectOtherRoom()을 호출하여 크로스 룸 PK 연결을 종료할 수 있습니다.XmagicResParser.setResPath(new File(getFilesDir(), "xmagic").getAbsolutePath());//loading//개인 디렉터리로 리소스 파일을 복사하며, 한 번만 수행하면 됩니다.XmagicResParser.copyRes(getApplicationContext());
XmagicResParser.setResPath(다운로드한 리소스 파일의 로컬 경로);
mTRTCCloud.setLocalVideoProcessListener(TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D, TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE, new TRTCCloudListener.TRTCVideoFrameListener() {@Overridepublic void onGLContextCreated() {// SDK 내부 OpenGL 환경이 생성되었으며, 이때 제3자 뷰티의 초기화 작업을 진행할 수 있습니다.if (mXmagicApi == null) {XmagicApi mXmagicApi = new XmagicApi(context, XmagicResParser.getResPath(), new XmagicApi.OnXmagicPropertyErrorListener());} else {mXmagicApi.onResume();}}@Overridepublic int onProcessVideoFrame(TRTCCloudDef.TRTCVideoFrame srcFrame, TRTCCloudDef.TRTCVideoFrame dstFrame) {// 제3자 뷰티 컴포넌트와 연동하기 위한 비디오 처리의 콜백if (mXmagicApi != null) {dstFrame.texture.textureId = mXmagicApi.process(srcFrame.texture.textureId, srcFrame.width, srcFrame.height);}return 0;}@Overridepublic void onGLContextDestory() {// SDK 내부 OpenGL 환경이 파기되었으며, 이때 제3자 뷰티 리소스 파기 작업을 진행할 수 있습니다.mXmagicApi.onDestroy();}});
public void enableDualStreamMode(boolean enable) {// 소형 스트림의 비디오 인코딩 매개변수(자체 정의 가능)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);}
// 원격 사용자 비디오 스트림을 구독할 때 선택 가능한 비디오 스트림의 유형mTRTCCloud.startRemoteView(userId, streamType, videoView);// 원격 사용자의 화면 크기를 언제든지 전환할 수 있습니다mTRTCCloud.setRemoteVideoStreamType(userId, streamType);
streamType 비디오 스트림 유형을 TRTC_VIDEO_STREAM_TYPE_SMALL으로 지정하여 저화질 소형 화면을 가져올 수 있습니다.TXCloudVideoView를 비디오 렌더링 컨트롤로 사용하며, SurfaceView와 TextureView 두 가지 렌더링 방식을 지원합니다. 아래에서는 렌더링 컨트롤 유형을 지정하는 방법과 비디오 렌더링 컨트롤을 업데이트하는 방법을 소개합니다.TXCloudVideoView으로 변환하려면 다음과 같이 코딩할 수 있습니다.//TextureView를 강제로 사용합니다TextureView textureView = findViewById(R.id.texture_view);TXCloudVideoView cloudVideoView = new TXCloudVideoView(context);cloudVideoView.addVideoView(textureView);//SurfaceView를 강제로 사용합니다SurfaceView surfaceView = findViewById(R.id.surface_view);TXCloudVideoView cloudVideoView = new TXCloudVideoView(surfaceView);
// 로컬 미리보기 화면 렌더링 컨트롤의 업데이트mTRTCCloud.updateLocalView(videoView);// 원격 사용자 비디오 렌더링 컨트롤의 업데이트mTRTCCloud.updateRemoteView(userId, streamType, videoView);
videoView를 대상 비디오 렌더링 컨트롤로 전달하고, streamType은 TRTC_VIDEO_STREAM_TYPE_BIG 및 TRTC_VIDEO_STREAM_TYPE_SUB만 지원됩니다.열거형 | 값 | 설명 |
ERR_TRTC_INVALID_USER_SIG | -3320 | 방 입장 매개변수 userSig가 올바르지 않습니다. TRTCParams.userSig이 비어 있는지 확인하세요. |
ERR_TRTC_USER_SIG_CHECK_FAILED | -100018 | UserSig 검증에 실패했습니다. 매개변수 TRTCParams.userSig이 올바르게 입력되었거나 만료되지 않았는지 확인하세요. |
열거형 | 값 | 설명 |
ERR_TRTC_CONNECT_SERVER_TIMEOUT | -3308 | 입장 요청이 시간 초과했습니다, 네트워크 연결이 끊겼는지 또는 VPN이 켜져 있는지 확인하세요. 4G로 전환하여 테스트할 수도 있습니다. |
ERR_TRTC_INVALID_SDK_APPID | -3317 | 입장 매개변수 sdkAppId가 잘못되었습니다. TRTCParams.sdkAppId이 비어 있는지 확인하세요. |
ERR_TRTC_INVALID_ROOM_ID | -3318 | 입장 매개변수 roomId가 잘못되었습니다. TRTCParams.roomId 또는 TRTCParams.strRoomId이 비어 있는지 확인하세요. roomId와 strRoomId는 혼용할 수 없습니다. |
ERR_TRTC_INVALID_USER_ID | -3319 | 입장 매개변수 userId가 올바르지 않습니다. TRTCParams.userId이 비어 있는지 확인하세요. |
ERR_TRTC_ENTER_ROOM_REFUSED | -3340 | 입장 요청이 거부되었습니다. enterRoom을 연속적으로 호출하여 동일한 ID의 방에 입장했는지 확인하세요. |
열거형 | 값 | 설명 |
ERR_CAMERA_START_FAIL | -1301 | Windows 또는 Mac 장치에서 카메라 구성 프로그램(드라이버)이 비정상일 경우, 카메라 열 수가 없습니다. 장치를 비활성화한 후 다시 활성화하거나, 기기를 재시작하거나, 구성 프로그램을 업데이트하세요. |
ERR_MIC_START_FAIL | -1302 | Windows 또는 Mac 장치에서 마이크 구성 프로그램(드라이버)이 비정상일 경우, 마이크 열 수가 없습니다. 장치를 비활성화한 후 다시 활성화하거나, 기기를 재시작하거나, 구성 프로그램을 업데이트하세요. |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | 카메라 장치에 권한이 없습니다. 일반적으로 모바일 장치에서 발생하며, 사용자가 권한을 거부했을 수 있습니다. |
ERR_MIC_NOT_AUTHORIZED | -1317 | 마이크 장치에 권한이 없습니다. 일반적으로 모바일 장치에서 발생하며, 사용자가 권한을 거부했을 수 있습니다. |
ERR_CAMERA_OCCUPY | -1316 | 카메라가 사용 중입니다. 다른 카메라를 열어 볼 수 있습니다. |
ERR_MIC_OCCUPY | -1319 | 마이크가 사용 중입니다. 예를 들어 모바일 장치에서 통화 중일 때 마이크를 열 수가 없습니다. |
setLocalRenderParams과 비디오 인코더 미러 setVideoEncoderMirror으로 나뉘며, 각각 로컬 미리보기 화면의 미러 효과와 비디오 인코딩 출력 화면의 미러 효과(원격 시청자 및 클라우드 레코딩의 미러링 모드)에 영향을 줍니다. 로컬 미리보기의 미러 효과가 원격 시청자 측에도 동시에 적용되도록 하려면 다음과 같이 코딩하십시오.// 로컬 화면의 렌더링 매개변수를 설정합니다.TRTCCloudDef.TRTCRenderParams params = new TRTCCloudDef.TRTCRenderParams();params.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_ENABLE; // 화면 미러 모드params.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL; // 화면 채우기 모드params.rotation = TRTCCloudDef.TRTC_VIDEO_ROTATION_0; // 화면 회전 각도mTRTCCloud.setLocalRenderParams(params);// 인코더 출력 화면 미러 모드를 설정합니다mTRTCCloud.setVideoEncoderMirror(true);
// 카메라 최대 줌 배율 가져오기(모바일 전용)float zoomRatio = mTRTCCloud.getDeviceManager().getCameraZoomMaxRatio();// 카메라 줌 배율의 설정(모바일 전용)// 범위는 1-5이며, 1은 가장 먼 시야(일반 렌즈)이고 5는 가장 가까운 시야(확대 렌즈)를 나타냅니다. 최대값은 5를 권장하며, 5를 초과하면 비디오 데이터가 흐릿해질 수 있습니다mTRTCCloud.getDeviceManager().setCameraZoomRatio(zoomRatio);
// 카메라 자동 초점 기능 켜기 또는 끄기(모바일 전용)mTRTCCloud.getDeviceManager().enableCameraAutoFocus(false);// 카메라 초점 위치의 설정(모바일 전용)// 해당 인터페이스를 사용하려면 먼저 enableCameraAutoFocus를 통해 자동 초점 기능을 꺼야 합니다mTRTCCloud.getDeviceManager().setCameraFocusPosition(int x, int y);
// 현재 전면 카메라인지 판단합니다(모바일 전용)boolean isFrontCamera = mTRTCCloud.getDeviceManager().isFrontCamera();// 전면 또는 후면 카메라의 전환(모바일 전용)// true 전달: 전면으로 전환; false 전달: 후면으로 전환mTRTCCloud.getDeviceManager().switchCamera(!isFrontCamera);
피드백