Last updated: 2021-08-13 17:04:51

    Demonstration

    You can download and install the demo app we provide to try out TRTC’s interactive live streaming features, including co-anchoring, anchor competition, low-latency watch, and on-screen comments.

    To quickly enable the interactive live video streaming feature, you can modify the demo app we provide and adapt it to your needs. You can also use the TRTCLiveRoom component and customize your own UI.

    Using the Demo App’s UI

    Step 1. Create an application

    1. Log in to the TRTC console and select Development Assistance > Demo Quick Run.
    2. Enter an application name such as TestLiveRoom and click Create.
    Note:

    This feature uses two basic PaaS services of Tencent Cloud, namely TRTC and IM. When you activate TRTC, IM will be activated automatically. IM is a value-added service. See Value-added Service Pricing for its billing details.

    Step 2. Download the SDK and demo app source code

    1. Download the SDK and source code of the demo app.
    2. Click Next.

    Step 3. Configure app project files

    1. In the Modify Configuration step, select the development platform in line with the source package downloaded.
    2. Find and open Android/Debug/src/main/java/com/tencent/liteav/debug/GenerateTestUserSig.java.
    3. Set parameters in GenerateTestUserSig.java as follows:
      • SDKAPPID: a placeholder by default. Set it to the actual `SDKAppID`.
      • SECRETKEY: a placeholder by default. Set it to the actual key.
    1. Click Next to complete the creation.
    2. After compilation, click Return to Overview Page.
    Note:

    The method for generating UserSig described in this document involves configuring SECRETKEY in client code. In this method, SECRETKEY may be easily decompiled and reversed, and if your key is disclosed, attackers can steal your Tencent Cloud traffic. Therefore, this method is suitable only for the local execution and debugging of the demo app.
    The correct UserSig distribution method is to integrate the calculation code of UserSig into your server and provide an application-oriented API. When UserSig is needed, your application can send a request to the business server for a dynamic UserSig. For more information, see How do I calculate UserSig on the server?.

    Step 4. Run the demo app

    Open the source code project TUILiveRoom with Android Studio (version 3.5 or above) and click Run.

    Step 5. Modify the demo app’s source code

    The Source folder in the source code contains two subfolders: ui and model. The ui subfolder contains UI code. The table below lists the files (folders) and the UI views they represent. You can refer to it when making UI changes.

    File or Folder Description
    anchor Implementation code for anchor-end views
    audience Implementation code for audience-end views
    common Implementation code for common UI components
    widget Common controls

    Tryout

    Note:

    You need at least two devices to try out the demo app.

    User A

    1. Enter a username (which must be unique) and log in.

    2. Tap Create Room.

    3. Enter a room name and tap Start.

    User B

    1. Enter a username (which must be unique).

    2. Enter the ID of the room created by user A, and tap Join.

    >! You can find the room ID at the top of user A’s room view.

    Listening for Room Status and Getting Room List for Co-Anchoring

    You can use LiveRoomManager to listen for room status.

    LiveRoomManager.getInstance().addCallback(new LiveRoomManager.RoomCallback() {
       /**
        * A room was created
        * @param roomId
        * @param callback  The result of internal processing
        */
       @Override
       public void onRoomCreate(int roomId, final LiveRoomManager.ActionCallback callback) {
           // doSomething
       }
        /**
        * A room was terminated
        * @param roomId
        * @param callback  The result of internal processing
        */
       @Override
       public void onRoomDestroy(int roomId, final LiveRoomManager.ActionCallback callback) {
           // doSomething
       }
        /**
        * The room list was obtained
        * @param callback
        */
       @Override
       public void onGetRoomIdList(final LiveRoomManager.GetCallback callback) {
           // The room list was obtained, which is used for co-anchoring and must be maintained by yourself
           if(callback != null) {
               if(success) {
                   // Callback successful, and the room list was returned
                   callback.onSuccess(roomList);
               } else {
                   // Failed to get the room list
                   callback.onError(code, message);
               }
           }
       }
    });
    

    Getting the room list may involve async operations. Using callbacks to get the list provides greater convenience and flexibility.

    Customizing UI

    The Source folder in the source code contains two subfolders: ui and model. The model subfolder contains the reusable open-source component TRTCLiveRoom. You can find the component’s APIs in TRTCLiveRoom.java and use them to customize your own UI.

    Step 1. Integrate the SDKs

    The TRTCLiveRoom component depends on the TRTC SDK and IM SDK. Follow the steps below to integrate them into your project.

    Method 1: adding dependencies via Maven

    1. Add the TRTC SDK and IM SDK dependencies to dependencies.
      dependencies {
         complie "com.tencent.liteav:LiteAVSDK_TRTC:latest.release"
         complie 'com.tencent.imsdk:imsdk:latest.release'
      }
      
      Note:

      You can view the latest version numbers of the two SDKs by visiting their GitHub pages at TRTC and IM.

    2. In defaultConfig, specify the CPU architecture to be used by the app.
      defaultConfig {
        ndk {
            abiFilters "armeabi-v7a"
        }
      }
      
    3. Click Sync Now to automatically download the SDKs and integrate them into your project.

    Method 2: adding dependencies through local AAR files
    If your access to the Maven repository is slow, you can download the ZIP files of the SDKs and manually integrate them into your project as instructed in the documents below.

    SDK Download Page Integration Guide
    TRTC SDK Download Integration document
    IM SDK Download Integration document

    Step 2. Configure permission requests and obfuscation rules

    Configure permission requests for your app in AndroidManifest.xml. The SDKs need the following permissions (on Android 6.0 and above, the camera and read storage permissions must be requested at runtime.)

    <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.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <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-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature android:name="android.hardware.camera.autofocus" />
    

    In the proguard-rules.pro file, add the SDK classes to the "do not obfuscate" list.

    -keep class com.tencent.** { *;}
    

    Step 3. Import the TRTCLiveRoom component

    Copy all the files in the directory below to your project:

    src/main/java/com/tencent/liteav/liveroom/model
    

    Step 4. Create an instance and log in

    1. Call the sharedInstance API to create an instance of the TRTCLiveRoom component.
    2. Create a TRTCLiveRoomConfig object, and set its useCDNFirst and CDNPlayDomain attributes.
      • useCDNFirst specifies the way audience watch live streams. true means that audience watch live streams over CDNs, which is cost-efficient but has high latency. false means that audience watch live streams under the low latency mode, the cost of which is between that of CDN live streaming and co-anchoring, but the latency is lower than 1 second.
      • CDNPlayDomain: specifies the domain name for CDN live streaming, which takes effect only if useCDNFirst is set to true. You can set it in CSS console > Domain Management.
    3. Call the login function to log in to the component, and set the key parameters as described below.
      Parameter Description
      SDKAPPID You can view the `SDKAPPID` in the TRTC console.
      userId ID of the current user, which is a string that can contain letters (a-z and A-Z), digits (0-9), hyphens (-), and underscores (_).
      userSig Tencent Cloud's proprietary security signature. To obtain one, see UserSig.
      config Global configuration information. Please initialize it during login as it cannot be modified after login.
      • `useCDNFirst`: specifies the way audience watch live streams. `true` means that audience watch live streams over CDNs, which is cost-efficient but has high latency. `false` means that audience watch live streams in the low latency mode, the cost of which is between that of CDN live streaming and co-anchoring, but the latency is within 1 second.
      • `CDNPlayDomain`: specifies the domain name for CDN live streaming, which takes effect only if `useCDNFirst` is set to `true`. You can set it in CSS console > **Domain Management**.
      callback Login callback. The code is 0 if login is successful.
      TRTCLiveRoom mLiveRoom = TRTCLiveRoom.sharedInstance(this);
      // useCDNFirst: `true` means that audience watch live streams over CDNs, and `false` means that audience watch live streams in the low latency mode.
      // yourCDNPlayDomain: the playback domain name for CDN live streaming
      TRTCLiveRoomDef.TRTCLiveRoomConfig config =
      new TRTCLiveRoomDef.TRTCLiveRoomConfig(useCDNFirst, yourCDNPlayDomain);
      mLiveRoom.login(SDKAPPID, userId, userSig, config,
      new TRTCLiveRoomCallback.ActionCallback() {
      @Override
      public void onCallback(int code, String msg) {
      if (code == 0)
      {
      // Logged in
      }
      }
      });

    Step 5. Create a room and push streams

    1. After performing step 4 to log in, call setSelfProfile to set your nickname and profile photo.
    2. Before streaming, you can call startCameraPreview to enable camera preview, add beauty filter buttons to the UI, and set beauty filters through getBeautyManager.
      Note:

      Only the Enterprise Edition SDK supports face changing and stickers.

    3. After setting beauty filters, call createRoom to create a live streaming room.
    4. Call startPublish to start streaming. To enable CDN live streaming, specify useCDNFirst and CDNPlayDomain in the TRTCLiveRoomConfig parameter, which is passed in during login, and specify streamID for playback when calling startPublish.

    // 1. Set the nickname and profile photo
    mLiveRoom.setSelfProfile("A", "your_face_url", null);

    // 2. Enable camera preview and set beauty filters before streaming
    TXCloudVideoView view = new TXCloudVideoView(context);
    parentView.add(view);
    mLiveRoom.startCameraPreview(true, view, null);
    mLiveRoom.getBeautyManager().setBeautyStyle(1);
    mLiveRoom.getBeautyManager().setBeautyLevel(6);

    // 3. Create a room
    TRTCLiveRoomDef.TRTCCreateRoomParam param = new TRTCLiveRoomDef.TRTCCreateRoomParam();
    param.roomName = "Test room";
    mLiveRoom.createRoom(123456789, param, new TRTCLiveRoomCallback.ActionCallback() {
    @Override
    public void onCallback(int code, String msg) {
    if (code == 0)
    {
    // 4. Start streaming and publish the streams to CDNs
    mLiveRoom.startPublish(mSelfUserId + "_stream", null);
    }
    }
    });

    Step 6. Play back streams

    1. After performing step 4 to log in, call setSelfProfile to set your nickname and profile photo.
    2. Get the latest room list from the backend.
      Note:

      The room list in the demo app is for demonstration only. The business logic of live streaming room lists varies significantly. Tencent Cloud does not provide list management services for the time being. Please manage the list by yourself.

    3. Call getRoomInfos to get short descriptions of the rooms, which are provided by anchors when they call createRoom to create the rooms.
      Note:

      If your room list already displays enough information, you can skip the step of calling getRoomInfos.

    4. Select a room, call enterRoom, with the room ID passed in to enter the room.
    5. Call startPlay, with the anchor’s userId passed in to start playback.
      • If the room list displays the userId of the anchor, you can call startPlay, passing in the anchor’s userId to start playback.
      • If you do not know the anchor's userId, you can find it in the onAnchorEnter event callback, which you will receive after entering the room. You can then call startPlay to start playback.

    // 1. Get the room list from the backend. Suppose it is `roomList`
    List<integer> roomList = GetRoomList();

    // 2. Call `getRoomInfos` to get the details of the room
    mLiveRoom.getRoomInfos(roomList, new TRTCLiveRoomCallback.RoomInfoCallback() {
    @Override
    public void onCallback(int code, String msg, List<trtcliveroomdef.trtcliveroominfo> list) {
    if (code == 0)
    {
    // After getting the room information, you can display on the anchor list page the anchor's nickname, profile photo, and other information
    }
    }
    })

    // 3. Select a `roomid` and enter the room
    mLiveRoom.enterRoom(roomid, null);

    // 4. After receiving the notification about the anchor’s entry, start playback
    mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
    @Override
    public void onAnchorEnter(final String userId) {
    // 5. Play the anchor's video
    mLiveRoom.startPlay(userId, mTXCloudVideoView, null);
    }
    });

    Step 7. Co-anchor

    1. Audience calls requestJoinAnchor to send a co-anchoring request to the anchor.
    2. The anchor receives a notification (TRTCLiveRoomDelegate#onRequestJoinAnchor) about the co-anchoring request.
    3. The anchor calls responseJoinAnchor to accept or decline the co-anchoring request.
    4. The audience receives the TRTCLiveRoomDelegate#responseCallback event notification, which carries the anchor’s response.
    5. If the anchor accepts the co-anchoring request, the audience can call startCameraPreview to turn the local camera on and then startPublish to push streams.
    6. The anchor receives a notification (TRTCLiveRoomDelegate#onAnchorEnter) that a new stream is available, which carries the audience’s userId.
    7. The anchor calls startPlay to play the audience’s video.

    // 1. The audience sends a co-anchoring request
    mLiveRoom.requestJoinAnchor(mSelfUserId + "requested to co-anchor",
    new TRTCLiveRoomCallback.ActionCallback() {
    @Override
    public void onCallback(int code, String msg) {
    if (code == 0)
    {
    // 4. The request is accepted by the anchor
    TXCloudVideoView view = new TXCloudVideoView(context);
    parentView.add(view);
    // 5. The audience turns the camera on and starts pushing streams
    mLiveRoom.startCameraPreview(true, view, null);
    mLiveRoom.startPublish(mSelfUserId + "_stream", null);
    }
    }
    });

    // 2. The anchor receives the co-anchoring request
    mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
    @Override
    public void onRequestJoinAnchor(final TRTCLiveRoomDef.TRTCLiveUserInfo userInfo,
    String reason, final int timeout)
    {
    // 3. The anchor accepts the co-anchoring request
    mLiveRoom.responseJoinAnchor(userInfo.userId, true, "agreed to co-anchor");
    }

    @Override
    public void onAnchorEnter(final String userId) {
    // 6. The anchor receives a notification that the audience has joined co-anchoring
    TXCloudVideoView view = new TXCloudVideoView(context);
    parentView.add(view);
    // 7. The anchor plays the audience’s video
    mLiveRoom.startPlay(userId, view, null);
    }
    });

    Step 8. Compete across rooms

    1. Anchor A calls requestRoomPK to send a competition request to anchor B.
    2. Anchor B receives the TRTCLiveRoomDelegate onRequestRoomPK notification.
    3. Anchor B calls responseRoomPK to accept or decline the competition request.
    4. Anchor B accepts the request and, after receiving the TRTCLiveRoomDelegate onAnchorEnter notification, calls startPlay to play anchor A's video.
    5. Anchor A receives the responseCallback notification, which specifies whether the competition request is accepted.
    6. The request is accepted, and after receiving the TRTCLiveRoomDelegate onAnchorEnter notification, anchor A calls startPlay to play anchor B's video.

    // Anchor A:
    // Create room 12345
    mLiveRoom.createRoom(12345, param, null);

    mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
    @Override
    public void onAnchorEnter(final String userId) {
    // 6. Receive a notification about anchor B’s entry
    mLiveRoom.startPlay(userId, mTXCloudVideoView, null);
    }
    });

    // 1. Send a competition request to anchor B
    mLiveRoom.requestRoomPK(54321, "B",
    new TRTCLiveRoomCallback.ActionCallback() {
    @Override
    public void onCallback(int code, String msg) {
    // 5. Receive a callback of whether the request is accepted by anchor B
    if (code == 0) {
    // Accepted
    } else {
    // Declined
    }
    }
    });

    // Anchor B:
    // Create room 54321
    mLiveRoom.createRoom(54321, param, null);

    // 2. Receive anchor A’s request
    mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
    @Override
    public void onRequestRoomPK(
    final TRTCLiveRoomDef.TRTCLiveUserInfo userInfo, final int timeout)
    {
    // 3. Accept anchor A's request
    mLiveRoom.responseRoomPK(userInfo.userId, true, "");
    }
    @Override
    public void onAnchorEnter(final String userId) {
    // 4. Receive a notification about anchor A’s entry and play anchor A's video
    mLiveRoom.startPlay(userId, mTXCloudVideoView, null);
    }
    });

    Step 9. Enable text chat and on-screen comments

    • Call sendRoomTextMsg to send common text messages. All users in the room will receive an onRecvRoomTextMsg callback.
      IM has its default content moderation rules. Text messages that contain restricted terms will not be forwarded by the cloud.
      // Sender: send text messages
      mLiveRoom.sendRoomTextMsg("Hello Word!", null);
      // Recipient: listen for text messages
      mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
      @Override
      public void onRecvRoomTextMsg(String roomId,
      String message, TRTCLiveRoomDef.TRTCLiveUserInfo userInfo)
      {
      Log.d(TAG, "Received a message from" + userInfo.userName + ": " + message);
      }
      });
    • Call sendRoomCustomMsg to send custom (signaling) messages. All users in the room will receive an onRecvRoomCustomMsg callback.
      Custom messages are often used to transfer custom signals, e.g., to give and broadcast likes.
      // For example, use "CMD_DANMU" to indicate on-screen comments and "CMD_LIKE" to indicate likes
      mLiveRoom.sendRoomCustomMsg("CMD_DANMU", "Hello world", null);
      mLiveRoom.sendRoomCustomMsg("CMD_LIKE", "", null);
      // Recipient: listen for custom messages
      mLiveRoom.setDelegate(new TRTCLiveRoomDelegate() {
      @Override
      public void onRecvRoomCustomMsg(String roomId, String cmd,
      String message, TRTCLiveRoomDef.TRTCLiveUserInfo userInfo) {
      if ("CMD_DANMU".equals(cmd)) {
      // Received an on-screen comment
      Log.d(TAG, "Received an on-screen comment from" + userInfo.userName + ": " + message);
      } else if ("CMD_LIKE".equals(cmd)) {
      // Received a like
      Log.d(TAG, userInfo.userName + "liked you.");
      }
      }
      });