Overview of Scenario-Based Solutions
소셜 엔터테인먼트
이커머스 라이브 방송
Audio/Video Call
원거리 실시간 조작
스마트 고객 서비스
AI 인터뷰
구현 방식 | 사용자 경험 | 리소스 소비 | 구현 로직 |
일반적으로 라이브 방송을 전환할 때 검은 화면이 먼저 나온 후 새로운 화면이 나타납니다. | 추가 리소스 소모 없음 | 간단하고 추가 로직 없음 | |
좀 괜찮습니다.라이브 방송을 전환할 때 해당 스트리머의 고정 플레이스홀더 이미지가 먼저 나온 후 새로운 화면이 나타납니다. | 좀 많습니다.각 스트리머마다 플레이스홀더 이미지를 추가로 저장하고 클라이언트에 로드해야 합니다 | 좀 복잡합니다.전환 전에 플레이스홀더 이미지를 추가로 비동기적으로 로드해야 합니다. | |
최고입니다. 라이브 방송 전환 시 전후 두 스트리머의 화면이 부드럽게 표시됩니다. | 많습니다.목록에서 2개의 스트림을 동시에 가져와야 하며, 라이브 방송에 들어간 후에는 1개의 스트림만 가져와도 됩니다. | 좀 복잡합니다. 여러 인스턴스를 사용하고 다른 인스턴스의 오디오 및 비디오 스트리밍을 제어해야 합니다 |

let src = TRTCSwitchRoomConfig()// 업무에 따라 해당 방 번호 및 입장 증명서를 생성하며 예시에서는 클라이언트에서 입장 증명서를 생성하지만, 온라인 업무에서는 백엔드에서 받으십시오.src.strRoomId = strRoomIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.switchRoom(src)

bgView = UIImageView(frame: self.view.bounds)// 해당 이미지는 해당 라이브 방송의 플레이스홀더 이미지여야 하며 사전에 업무상에서 받아야 합니다bgView.image = UIImage(named: "1.png")bgView.contentMode = .scaleAspectFillbgView.translatesAutoresizingMaskIntoConstraints = falseself.view.insertSubview(bgView, at: 0)NSLayoutConstraint.activate([bgView.topAnchor.constraint(equalTo: view.topAnchor),bgView.bottomAnchor.constraint(equalTo: view.bottomAnchor),bgView.leadingAnchor.constraint(equalTo: view.leadingAnchor),bgView.trailingAnchor.constraint(equalTo: view.trailingAnchor),])
DispatchQueue.main.async {UIView.transition(with: self.bgView,duration: 0,options: .transitionCrossDissolve,animations: {// 업무에 따라 해당 플레이스홀더 이미지로 전환합니다self.bgView.image = UIImage(named: strRoomId)}, completion: nil)}let src = TRTCSwitchRoomConfig()// 업무에 따라 해당 방 번호 및 입장 증명서를 생성하며, 예시에서는 클라이언트에서 입장 증명서를 생성하지만, 온라인 업무에서는 백엔드에서 받으십시오.src.strRoomId = strRoomIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.switchRoom(src)
// 비디오 스트림 가져오기func onUserVideoAvailable(_ userId: String, available: Bool) {if available {trtcCloud.startRemoteView(userId, streamType: .big, view: view)} else {trtcCloud.stopRemoteView(userId, streamType: .big)}}// 첫 번째 비디오 프레임 렌더링이 시작될 때 플레이스홀더 이미지를 배경으로 전환하고 비디오 화면을 표시합니다.func onFirstVideoFrame(_ userId: String, streamType: TRTCVideoStreamType, width: Int32, height: Int32) {// 여기는 배경 이미지와 비디오 렌더링 컨트롤의 전후 순서를 조정하는 곳이고 실제 업무 상황에 따라 조정합니다.self.view.exchangeSubview(at: 1, withSubviewAt: 0)}


import Foundationimport ObjectiveCimport TXLiteAVSDK_Professional@objc protocol SubCloudHelperDelegate : NSObjectProtocol {@objc optional func onUserVideoAvailableWithSubId(subId: Int, userId: String, available: Bool)}class SubCloudHelper:NSObject,TRTCCloudDelegate {var trtcCloud: TRTCCloud!var subId: Int!weak var delegate : SubCloudHelperDelegate? = nilfunc initWithSubId(subId: Int, trtcIns: TRTCCloud) {self.subId = subIdself.trtcCloud = trtcInsself.trtcCloud.addDelegate(self)}func getCloud()->TRTCCloud {return trtcCloud}func onUserVideoAvailable(_ userId: String, available: Bool) {if self.delegate?.onUserVideoAvailableWithSubId?(subId: subId, userId: userId, available: available) == nil {return}}}
let trtcCloud = TRTCCloud()let subCloudHelper = SubCloudHelper()override func viewDidLoad() {super.viewDidLoad()subCloudHelper.initWithSubId(subId: 0, trtcIns: trtcCloud.createSub())subCloudHelper.delegate = self}
private var atRoom: Bool = falsevar pageViewController: UIPageViewController!var pageZero: UIViewController!var pageOne: UIViewController!var pageTwo: UIViewController!var pages: [UIViewController] = []var curPageIdx = 0var curIsSub = falsefunc setupPages() {pageViewController = UIPageViewController(transitionStyle: .scroll,navigationOrientation: .vertical)pageViewController.dataSource = selfpageViewController.delegate = selfaddChild(pageViewController)view.addSubview(pageViewController.view)pageViewController.didMove(toParent: self)// pagespageZero = UIViewController()pageZero.view.backgroundColor = .blackpageOne = UIViewController()pageOne.view.backgroundColor = .blackpageTwo = UIViewController()pageTwo.view.backgroundColor = .blackpages = [pageZero, pageOne, pageTwo]pageViewController.setViewControllers([pages[curPageIdx]], direction: .forward, animated: false)}
// 다음/이전 페이지 가져오기func getShowPage(isNext: Bool) -> UIViewController {var newPageIdx = 0if isNext {newPageIdx = curPageIdx + 1} else {newPageIdx = curPageIdx - 1}if newPageIdx >= pages.count {newPageIdx = 0} else if newPageIdx < 0 {newPageIdx = pages.count - 1}return pages[newPageIdx]}extension RtcDuplexVC: UIPageViewControllerDataSource {func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {return getShowPage(isNext: false)}func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {return getShowPage(isNext: true)}}
// 메인 인스턴스로 방에 들어가기// 실제 업무에 따라 sdkAppId, roomID, strRoomId, userId 및 userSig를 교체합니다// 예시에서는 클라이언트에서 userSig를 생성하며, 온라인 업무의 경우 백엔드에서 가져오십시오let params = TRTCParams()params.sdkAppId = UInt32(SDKAppID)params.roomId = 0params.strRoomId = strRoomIdLst.first ?? "1"params.userId = userIdparams.role = .anchorparams.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringtrtcCloud.addDelegate(self)trtcCloud.enterRoom(params, appScene: .LIVE)// 하위 인스턴스로 다음 방을 미리 로드합니다// 실제 업무에 따라 sdkAppId, roomID, strRoomId, userId 및 userSig를 교체합니다// 예시에서는 클라이언트 사용하여 userSig를 생성하며 온라인 업무의 경우 백엔드에서 가져오십시오let subParams = TRTCParams()subParams.sdkAppId = UInt32(SDKAppID)subParams.roomId = 0subParams.strRoomId = strRoomIdLst[1]subParams.userId = userIdsubParams.role = .anchorsubParams.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as StringsubCloudHelper.trtcCloud.enterRoom(subParams, appScene: .LIVE)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)
func getPageByIdx(isNext: Bool) -> UIViewController {var newPageIdx = curPageIdxif isNext {newPageIdx += 1}if newPageIdx >= pages.count {newPageIdx = 0}return pages[newPageIdx]}extension RtcDuplexVC: TRTCCloudDelegate {func onUserVideoAvailable(_ userId: String, available: Bool) {if available {trtcCloud.startRemoteView(userId, streamType: .big, view: getPageByIdx(isNext: curIsSub).view)} else {trtcCloud.stopRemoteView(userId, streamType: .big)}}}extension RtcDuplexVC: SubCloudHelperDelegate {func onUserVideoAvailableWithSubId(subId: Int, userId: String, available: Bool) {if available {subCloudHelper.trtcCloud.startRemoteView(userId, streamType: .big, view: getPageByIdx(isNext: !curIsSub).view)} else {subCloudHelper.trtcCloud.stopRemoteView(userId, streamType: .big)}}}
func updateCurRoomIdx(isNext: Bool) {if isNext {curRoomIdx += 1if curRoomIdx >= strRoomIdLst.count {curRoomIdx = 0}} else {curRoomIdx -= 1if curRoomIdx < 0 {curRoomIdx = strRoomIdLst.count - 1}}}// 실제 업무 로직에 따라 방 번호를 전환해야 합니다func updateNewRoom(isNext: Bool) {var newRoomIdx = 0if isNext{newRoomIdx = curRoomIdx + 1} else {newRoomIdx = curRoomIdx - 1}if newRoomIdx >= strRoomIdLst.count {newRoomIdx = 0} else if newRoomIdx < 0 {newRoomIdx = strRoomIdLst.count - 1}let newRoomStrId = strRoomIdLst[newRoomIdx]let src = TRTCSwitchRoomConfig()src.strRoomId = newRoomStrIdsrc.userSig = GenerateTestUserSig.genTestUserSig(identifier: userId) as Stringif curIsSub {trtcCloud.switchRoom(src)trtcCloud.muteAllRemoteAudio(true)} else {subCloudHelper.trtcCloud.switchRoom(src)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}}extension RtcDuplexVC: UIPageViewControllerDelegate {func pageViewController(_ pageViewController: UIPageViewController,didFinishAnimating finished: Bool,previousViewControllers: [UIViewController],transitionCompleted completed: Bool) {if completed {guard let currentVC = pageViewController.viewControllers?.first else {return}if let index = pages.firstIndex(of: currentVC) {// 위-아래로 스크롤하는 판단 기준 가져오기let iden = index - curPageIdx// 현재 표시된 페이지의 번호 업데이트하기curPageIdx = index// 아래로 스크롤if iden == 1 || iden == -2 {// 현재 위치한 방의 번호 업데이트하기updateCurRoomIdx(isNext: true)// 현재 표시된 페이지의 인스턴스 업데이트하기curIsSub.toggle()// 방 업데이트하기updateNewRoom(isNext: true)}// 위로 스크롤if iden == -1 || iden == 2 {// 방 업데이트하기updateNewRoom(isNext: false)// 현재 위치한 방의 번호 업데이트하기updateCurRoomIdx(isNext: false)// 현재 표시된 페이지의 인스턴스 업데이트하기curIsSub.toggle()trtcCloud.muteAllRemoteAudio(true)subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}// 현재 방의 음소거 해제하기if curIsSub {subCloudHelper.trtcCloud.muteAllRemoteAudio(false)} else {trtcCloud.muteAllRemoteAudio(false)}}}}}

// 라이브 방송 진입 로직의 처리@objc func enterBtnClick() {// 위-아래 스크롤 목록의 UI 컴포넌트의 숨김self.enterBtn.isHidden = true// 라이브 방송 진입 후 UI 컴포넌트의 표시self.exitBtn.isHidden = false// ...self.atRoom = true// 라이브 방송 진입 후 위-아래 스크롤의 금지pageViewController.dataSource = nil// 사전 로드의 중지if curIsSub{trtcCloud.muteAllRemoteVideoStreams(true)} else {subCloudHelper.trtcCloud.muteAllRemoteAudio(true)}}// 라이브 방송 퇴장 로직의 처리@objc func exitBtnClick() {// 라이브 방송 중 UI 컴포넌트의 숨김self.enterBtn.isHidden = false// 위-아래 스크롤 목록의 UI 컴포넌트의 표시self.exitBtn.isHidden = trueself.atRoom = false// 위-아래 스크롤 목록 진입 후 위-아래 스크롤의 복원pageViewController.dataSource = self// 사전 로드의 재개if curIsSub{trtcCloud.muteAllRemoteVideoStreams(false)} else {subCloudHelper.trtcCloud.muteAllRemoteAudio(false)}}
구현 방식 | 사용자 체험 | 리소스 소비 | 구현 로직 |
일반적으로 리스트를 스크롤할 때 두 개의 라이브 방송을 동시에 볼 수 없으며 페이지가 완전히 전환된 후에 해당 라이브 방송이 표시됩니다. 플레이스홀더 이미지를 사용하여 사용자 체험을 향상시킬 수 있습니다. | 리스트에는 하나의 트래픽 소모만 있으며, 하나의 비디오 재생 객체가 사용됩니다. | 간단합니다.필요에 따라 플레이스홀더 이미지를 설정합니다. | |
좋습니다. 두 개의 라이브 방송에 동시에 진입하고 다음 라이브를 미리 로드하여, 리스트를 스크롤할 때 현재와 다음 라이브 방송을 동시에 볼 수 있습니다. | 리스트에는 두 개의 트래픽 소모가 발생하며 두 개의 비용이 발생하고, 두 개의 비디오 재생 객체가 사용됩니다. | 복잡합니다. 여러 인스턴스를 사용하고 다른 인스턴스의 오디오 및 비디오 스트리밍을 제어해야 합니다 |

public class ScrollSwitchRoomActivity extends TRTCBaseActivity {PageAdapter mAdapter;public String[] mRoomIds;private TRTCCloud mTRTCCloud;private TXCloudVideoView mRemoteVideoView;private int mCurPos = -1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scroll_switch_room);//제목 표시줄 숨기기getSupportActionBar().hide();mRoomIds = new String[]{"1231", "1232", "1233"};if (checkPermission()) {initView();}}@Overrideprotected void onPermissionGranted() {initView();}private void initView() {mAdapter = new PageAdapter(this, mRoomIds);ViewPager2 viewPager = findViewById(R.id.viewPager);viewPager.setAdapter(mAdapter);//viewPager 슬라이드 방향의 설정viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);// viewPager 프리로드의 설정viewPager.setOffscreenPageLimit(1);// 페이지 전환 리스너의 추가viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {public void onPageSelected(int position) {Log.d("ScrollSwitchRoom", "onPageSelected: " + position);if (mCurPos == position) {return;}RecyclerView recyclerViewImpl = (RecyclerView) viewPager.getChildAt(0);// 현재 방에서 먼저 나가기exitRoom();// 다음 방으로 들어가기View itemView = recyclerViewImpl.getChildAt(position);mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);enterRoom(position);mCurPos = position;}});// Initialize your views heremTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());mTRTCCloud.addListener(mTRTCCloudListener);}private void enterRoom(int roomIdIndex) {TRTCCloudDef.TRTCParams mTRTCParams = new TRTCCloudDef.TRTCParams();mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;mTRTCParams.userId = "123";mTRTCParams.strRoomId = mRoomIds[roomIdIndex];mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);mTRTCParams.role = TRTCCloudDef.TRTCRoleAudience;mTRTCCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}private TRTCCloudListener mTRTCCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mRemoteVideoView);} else {mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}public void onError(int errCode, String errMsg, Bundle extraInfo) {// print ErrorLog.e("ScrollSwitchRoom", "Error: " + errCode + " " + errMsg);}};private void exitRoom() {mTRTCCloud.stopAllRemoteView();mTRTCCloud.exitRoom();// mTRTCCloud.setListener(null);}public class PageAdapter extends RecyclerView.Adapter<PageAdapter.PageViewHolder> {private Context context;public String[] mRoomIds;public PageAdapter(Context context, String[] roomIds) {this.context = context;this.mRoomIds = roomIds;}public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_scroll_page, parent, false);return new PageViewHolder(view);}public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {TextView textView = holder.itemView.findViewById(R.id.tv_room_number);textView.setText(getString(R.string.switchroom_roomid) + ":" + mRoomIds[position]);}public int getItemCount() {return mRoomIds.length;}public int getItemViewType(int position) {return position;}class PageViewHolder extends RecyclerView.ViewHolder {PageViewHolder(@NonNull View itemView) {super(itemView);}}}@Overrideprotected void onDestroy() {super.onDestroy();exitRoom();}}
<?xml version="1.0" encoding="utf-8"?><androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent" />
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/item_layout"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/iv_placeholder"android:scaleType="centerCrop"android:background="@drawable/placeholder_img"android:layout_width="match_parent"android:layout_height="match_parent"/><com.tencent.rtmp.ui.TXCloudVideoViewandroid:id="@+id/txcvv_main_local"android:layout_width="match_parent"android:layout_height="match_parent" /><TextViewandroid:id="@+id/tv_room_number"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintEnd_toEndOf="@id/item_layout"app:layout_constraintStart_toStartOf="@id/item_layout" /></androidx.constraintlayout.widget.ConstraintLayout>

public class ScrollSwitchRoomDualActivity extends TRTCBaseActivity {PageAdapter mAdapter;public String[] mRoomIds;private TRTCCloud mTRTCCloud;private TRTCCloud mSubCloud;private TXCloudVideoView mRemoteVideoView;private TXCloudVideoView mSubRemoteVideoView;private Boolean mIsInMainRoom = null;private int mCurPos = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scroll_switch_room);//제목 표시줄 숨기기getSupportActionBar().hide();mRoomIds = new String[]{"1231", "1232", "1233"};if (checkPermission()) {initView();}}@Overrideprotected void onPermissionGranted() {initView();}private void initView() {mAdapter = new PageAdapter(this,mRoomIds);ViewPager2 viewPager = findViewById(R.id.viewPager);viewPager.setAdapter(mAdapter);//viewPager 슬라이드 방향의 설정viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);// viewPager 프리로드의 설정viewPager.setOffscreenPageLimit(1);// 페이지 전환 리스너의 추가viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {public void onPageSelected(int position) {Log.d("ScrollSwitchRoom", "onPageSelected: " + position);RecyclerView recyclerViewImpl = (RecyclerView) viewPager.getChildAt(0);if (mIsInMainRoom == null) {View itemView = recyclerViewImpl.getChildAt(position);mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);View subItemView = recyclerViewImpl.getChildAt(position + 1);mSubRemoteVideoView = subItemView.findViewById(R.id.txcvv_main_local);enterRoom();mIsInMainRoom = true;} else {if (mIsInMainRoom) {mTRTCCloud.muteAllRemoteAudio(true);mSubCloud.muteAllRemoteAudio(false);} else {mTRTCCloud.muteAllRemoteAudio(false);mSubCloud.muteAllRemoteAudio(true);}if (position != (mRoomIds.length - 1)) {String roomId;TRTCCloud trtcCloud;if (mCurPos < position) {// 화면을 위로 슬라이드roomId = mRoomIds[position + 1];trtcCloud = mIsInMainRoom ? mTRTCCloud : mSubCloud;View itemView = recyclerViewImpl.getChildAt(position + 1);if (mIsInMainRoom) {mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);} else {mSubRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);}} else {//화면을 아래로 슬라이드roomId = mRoomIds[position];trtcCloud = mIsInMainRoom ? mSubCloud : mTRTCCloud;View itemView = recyclerViewImpl.getChildAt(position);if (mIsInMainRoom) {mSubRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);} else {mRemoteVideoView = itemView.findViewById(R.id.txcvv_main_local);}}switchRoom(roomId, trtcCloud);}mIsInMainRoom = !mIsInMainRoom;}mCurPos = position;}});// Initialize your views heremTRTCCloud = TRTCCloud.sharedInstance(getApplicationContext());mSubCloud = mTRTCCloud.createSubCloud();}/*** 초기화 시에만 방 입장을 호출하고 이후 방을 전환할 때는 switchRoom을 호출합니다.*/private void enterRoom() {mTRTCCloud.addListener(mTRTCCloudListener);mSubCloud.addListener(mSubCloudListener);TRTCCloudDef.TRTCParams mTRTCParams = new TRTCCloudDef.TRTCParams();mTRTCParams.sdkAppId = GenerateTestUserSig.SDKAPPID;mTRTCParams.userId = "123";// mTRTCParams.roomId = Integer.parseInt(roomId);mTRTCParams.strRoomId = mRoomIds[0];mTRTCParams.userSig = GenerateTestUserSig.genTestUserSig(mTRTCParams.userId);mTRTCParams.role = TRTCCloudDef.TRTCRoleAudience;mTRTCCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);mTRTCParams.strRoomId = mRoomIds[1];mSubCloud.muteAllRemoteAudio(true);mSubCloud.enterRoom(mTRTCParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);}private TRTCCloudListener mTRTCCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mTRTCCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mRemoteVideoView);} else {mTRTCCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}public void onError(int errCode, String errMsg, Bundle extraInfo) {// print ErrorLog.e("ScrollSwitchRoom", "Error: " + errCode + " " + errMsg);}public void onSwitchRoom(long err, String errMsg) {// Switch room}};private TRTCCloudListener mSubCloudListener = new TRTCCloudListener() {public void onEnterRoom(long result) {if (result == 0) {// Enter room success} else {// Enter room failed}}public void onExitRoom(int reason) {// Exit room}@Overridepublic void onUserVideoAvailable(String userId, boolean available) {super.onUserVideoAvailable(userId, available);if (available) {mSubCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, mSubRemoteVideoView);} else {mSubCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);}}};private void exitRoom() {mTRTCCloud.stopAllRemoteView();mTRTCCloud.exitRoom();mTRTCCloud.setListener(null);mSubCloud.stopAllRemoteView();mSubCloud.exitRoom();mSubCloud.setListener(null);}private void switchRoom(String roomId, TRTCCloud trtcCloud) {TRTCCloudDef.TRTCSwitchRoomConfig config = new TRTCCloudDef.TRTCSwitchRoomConfig();// config.roomId = Integer.parseInt(roomId);config.strRoomId = roomId;trtcCloud.switchRoom(config);}public class PageAdapter extends RecyclerView.Adapter<PageAdapter.PageViewHolder> {private Context context;public String[] mRoomIds;public PageAdapter(Context context, String[] roomIds) {this.context = context;this.mRoomIds = roomIds;}public PageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(context).inflate(R.layout.item_scroll_page, parent, false);return new PageViewHolder(view);}public void onBindViewHolder(@NonNull PageViewHolder holder, int position) {TextView textView = holder.itemView.findViewById(R.id.tv_room_number);textView.setText(getString(R.string.switchroom_roomid) + ":" + mRoomIds[position]);}public int getItemCount() {return mRoomIds.length;}public int getItemViewType(int position) {return position;}class PageViewHolder extends RecyclerView.ViewHolder {PageViewHolder(@NonNull View itemView) {super(itemView);}}}@Overrideprotected void onDestroy() {super.onDestroy();exitRoom();}}
피드백