客户端实现(基于语聊房组件)

更新时间: 2023/09/21 08:10:26

本文档为您展示通过语聊房组件实现语聊房场景的相关步骤,帮助您在业务中实现麦位管理、低延时语音互动、文字聊天等能力。

开发环境要求

开发环境要求如下:

环境要求 说明
JDK 版本 1.8.0 及以上版本
Android API 版本 API 21 及以上版本
Android Studio 版本 5.0 及以上版本
CPU架构 ARM 64、ARMV7
IDE Android Studio
其他 依赖 Androidx,不支持 support 库。
Android 系统 5.0 及以上版本的真机。

前提条件

已开通能力

方案架构

语聊房组件的业务流.png

方案架构说明如下:

  • 主播、连麦者和观众加入同一个音视频房间。
  • 主播和连麦者在音视频房间内进行音频流的实时发布和订阅。
  • 观众在音视频房间内仅订阅音频流,不发布音频流。

API调用时序图

sequenceDiagram
    autonumber
    actor hostClientA as 主播A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众B client

    Note over hostClientA, audienceB: 主播开播
    hostClientA ->> voiceRoomKitA:createRoom
    voiceRoomKitA ->> app_server:createRoom
    app_server -->> hostClientA:房间信息
    hostClientA ->> voiceRoomKitA:joinRoom
    voiceRoomKitA ->> app_server:joinRoom
    app_server -->> hostClientA:加入成功
    hostClientA ->> voiceRoomKitA:submitSeatRequest上麦
    voiceRoomKitA ->> app_server:submitSeatRequest上麦
    hostClientA ->> voiceRoomKitA:unmuteMyAudio
    voiceRoomKitA ->> app_server:unmuteMyAudio

    Note over hostClientA, audienceB: 观众进入房间
    audienceB ->> voiceRoomKitB:joinRoom
    voiceRoomKitB ->> app_server:joinRoom
    app_server -->> audienceB:房间信息
    audienceB ->> voiceRoomKitB:unmuteMyAudio
    voiceRoomKitB ->> app_server:unmuteMyAudio

sequenceDiagram
    autonumber
    actor hostClientA as 主播A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众B client

    Note over hostClientA, audienceB: 抱观众上麦
    hostClientA ->> voiceRoomKitA:邀请上麦sendSeatInvitation
    voiceRoomKitA ->> app_server:邀请上麦sendSeatInvitation
    app_server ->> voiceRoomKitB:自动同意上麦onSeatInvitationAccepted
    voiceRoomKitB ->> audienceB:自动同意上麦onSeatInvitationAccepted
    app_server ->> voiceRoomKitB:麦位变更onSeatListChanged
    voiceRoomKitB ->> audienceB:麦位变更onSeatListChanged
    app_server ->> voiceRoomKitA:自动同意上麦onSeatInvitationAccepted
    voiceRoomKitA ->> hostClientA:自动同意上麦onSeatInvitationAccepted
    app_server ->> voiceRoomKitA:麦位变更onSeatListChanged
    voiceRoomKitA ->> hostClientA:麦位变更onSeatListChanged
    audienceB ->> audienceB:刷新UI
    hostClientA ->> hostClientA:刷新UI

    Note over hostClientA, audienceB: 踢观众下麦
    hostClientA ->> voiceRoomKitA:主播踢观众B下麦kickSeat
    voiceRoomKitA ->> app_server:主播踢观众B下麦kickSeat
    app_server ->> voiceRoomKitB:主播踢观众B下麦onSeatKicked
    voiceRoomKitB ->> audienceB:主播踢观众B下麦onSeatKicked
    app_server ->> voiceRoomKitB:麦位变更onSeatListChanged
    voiceRoomKitB ->> audienceB:麦位变更onSeatListChanged
    app_server ->> voiceRoomKitA:主播踢观众B下麦onSeatKicked
    voiceRoomKitA ->> hostClientA:主播踢观众B下麦onSeatKicked
    app_server ->> voiceRoomKitA:麦位变更onSeatListChanged
    voiceRoomKitA ->> hostClientA:麦位变更onSeatListChanged
    audienceB ->> audienceB:刷新UI
    hostClientA ->> hostClientA:刷新UI
 

观众申请上麦的时序图如下:

sequenceDiagram
    autonumber
    actor hostClientA as 主播A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众B client


    audienceB->>voiceRoomKitB: 申请上麦submitSeatRequest
    voiceRoomKitB->>app_server: 申请上麦submitSeatRequest
    app_server-->>voiceRoomKitB: 麦位变更onSeatListChanged
    voiceRoomKitB-->>audienceB: 麦位变更onSeatListChanged
    app_server-->>voiceRoomKitA: 观众B申请上麦onSeatRequestSubmitted
    voiceRoomKitA-->>hostClientA: 观众B申请上麦onSeatRequestSubmitted
    app_server-->>voiceRoomKitA: 麦位变更onSeatListChanged
    voiceRoomKitA-->>hostClientA: 麦位变更onSeatListChanged
    audienceB->>audienceB: 刷新UI
    hostClientA->>hostClientA: 刷新UI

    alt 主播同意上麦申请
        hostClientA->>voiceRoomKitA: 主播同意上麦申请approveSeatRequest
        voiceRoomKitA->>app_server: 主播同意上麦申请approveSeatRequest
        app_server-->>voiceRoomKitA: 主播同意上麦申请onSeatRequestApproved
        voiceRoomKitA-->>hostClientA: 主播同意上麦申请onSeatRequestApproved
        app_server-->>voiceRoomKitB: 主播同意上麦申请onSeatRequestApproved
        voiceRoomKitB-->>audienceB: 主播同意上麦申请onSeatRequestApproved
        app_server-->>voiceRoomKitB: 麦位变更onSeatListChanged
        voiceRoomKitB-->>audienceB: 麦位变更onSeatListChanged
        audienceB->>audienceB: 刷新UI
        hostClientA->>hostClientA: 刷新UI
    else 主播拒绝上麦申请
        hostClientA->>voiceRoomKitA: 主播不同意上麦申请rejectSeatRequest
        voiceRoomKitA->>app_server: 主播不同意上麦申请rejectSeatRequest
        app_server-->>voiceRoomKitA: 主播拒绝观众B上麦onSeatRequestRejected
        voiceRoomKitA-->>hostClientA: 主播拒绝观众B上麦onSeatRequestRejected
        app_server-->>voiceRoomKitB: 主播拒绝观众B上麦onSeatRequestRejected
        voiceRoomKitB-->>audienceB: 主播拒绝观众B上麦onSeatRequestRejected
        app_server-->>voiceRoomKitB: 麦位变更onSeatListChanged
        voiceRoomKitB-->>audienceB: 麦位变更onSeatListChanged
        audienceB->>audienceB: 刷新UI
        hostClientA->>hostClientA: 刷新UI
    end
  

观众取消申请上麦的时序图如下:

sequenceDiagram
    autonumber
    participant hostClientA as 主播A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    participant audienceB as 观众B client

    audienceB->>voiceRoomKitB: 取消申请上麦cancelSeatRequest
    voiceRoomKitB->>app_server: 取消申请上麦cancelSeatRequest
    app_server->>voiceRoomKitA: 观众B取消上麦onSeatRequestCancelled
    voiceRoomKitA->>hostClientA: 观众B取消上麦onSeatRequestCancelled
    app_server->>voiceRoomKitA: 麦位变更onSeatListChanged
    hostClientA->>hostClientA: 刷新UI
    app_server->>voiceRoomKitB: 观众B取消上麦onSeatRequestCancelled
    voiceRoomKitB->>audienceB: 观众B取消上麦onSeatRequestCancelled
    app_server->>voiceRoomKitB: 麦位变更onSeatListChanged
    audienceB->>audienceB: 刷新UI

观众主动下麦的时序图如下:

sequenceDiagram
    autonumber
    participant hostClientA as 主播A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    participant audienceB as 观众B client

    audienceB->>voiceRoomKitB: 下麦leaveSeat
    voiceRoomKitB->>app_server: 下麦leaveSeat
    app_server->>voiceRoomKitA: 观众B成功下麦onSeatLeave
    voiceRoomKitA->>hostClientA: 观众B成功下麦onSeatLeave
    app_server->>voiceRoomKitA: 麦位变更onSeatListChanged
    hostClientA->>hostClientA: 刷新UI
    app_server->>voiceRoomKitB: 观众B成功下麦onSeatLeave
    voiceRoomKitB->>audienceB: 观众B成功下麦onSeatLeave
    app_server->>voiceRoomKitB: 麦位变更onSeatListChanged
    audienceB->>audienceB: 刷新UI

示例项目源码

语聊房示例项目源码

集成 VoiceRoom 组件

步骤1 集成 VoiceRoom 组件

  1. 若您需要创建新项目,在 Android Studio 里,在顶部菜单依次选择 File > New > New Project 新建工程,再依次选择 Phone and Tablet > Empty Activity,单击 Next
    image

    创建 Android 项目成功后,Android Studio 会自动开始同步 gradle, 您需要等同步成功后再进行下一步操作。

  2. 在项目对应模块的 build.gradle 中加入以下行,添加依赖。
    implementation 'com.netease.yunxin.kit.voiceroom:voiceroomkit:x.x.x'
    
    其中,x.x.x 为VoiceRoom 组件对应版本的版本号。
  3. 在项目对应的根目录的 build.gradle 中加入以下行。
    allprojects {
        repositories {
            mavenCentral()
        }
    }
    

步骤2 配置权限

app/src/main/AndroidManifest.xml 文件中添加类似如下代码,添加相应的设备权限。

//网络相关
<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.CHANGE_WIFI_STATE"/>
//防止通话过程中锁屏
<uses-permission android:name="android.permission.WAKE_LOCK"/>
//录音权限
<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.WRITE_EXTERNAL_STORAGE"/>
//蓝牙 startBluetoothSco 会用到此权限
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
//获取设备信息
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

//允许应用程序使用camera硬件资源
<uses-feature android:name="android.hardware.camera"/>
//自动对焦
<uses-feature android:name="android.hardware.camera.autofocus"/>
        ......//APP需要的其他设备权限


初始化组件

在调用 SDK 其他接口之前,您首先需要完成初始化操作。

  1. 配置初始化相关参数。

  2. 调用 initialize 方法完成初始化操作。

示例代码如下:

Map<String, String> extras = new HashMap<>();
extras.put("serverUrl", AppConfig.getServerUrl()); 
NEVoiceRoomKit.getInstance()
    .initialize(
        context,
        new NEVoiceRoomKitConfig(appKey, extras),
        new NEVoiceRoomCallback<Unit>() {
            @Override
            public void onSuccess(@Nullable Unit unit) {
            
            }

            @Override
            public void onFailure(int code, @Nullable String msg) {
            
            }
        });

登录鉴权

请求 SDK 进行登录鉴权,您只有完成 SDK 登录鉴权才可以创建语聊房房间。

示例代码如下:

NEVoiceRoomKit.getInstance()
.login(
    "your account",
    "your token",
    new NEVoiceRoomCallback<Unit>() {

        @Override
        public void onSuccess(Unit unit) {

        }

        @Override
        public void onFailure(int code, String msg) {
        
        }
    });

示例代码中的your accountyour token是您的应用服务器向 NERoom 服务器申请创建账号时,返回的 userUuiduserToken 的值,具体请参见创建账号

实现语聊房

1. 主播开播

  1. 主播调用 createRoom 接口创建房间。

创建房间NECreateVoiceRoomParams参数说明:

参数 类型 描述
title String 房间名。
最大长度为 64 个字符。
nick String 昵称。
seatCount int 麦位个数,默认 8 个,取值范围为 1~20 。
configId int 模版 ID。获取方法请参见如何获取模板 ID
cover String 封面,请填写封面图片的 URL 地址。
extraData String 扩展字段。

示例代码如下:

NECreateVoiceRoomParams createVoiceRoomParams =
        new NECreateVoiceRoomParams(
            "roomName",
            "userName",
            9,
            569,
            cover,
            null);
    NEVoiceRoomKit.getInstance()
        .createRoom(
            createVoiceRoomParams,
            new NECreateVoiceRoomOptions(),
            new NEVoiceRoomCallback<NEVoiceRoomInfo>() {
            @Override
            public void onSuccess(@Nullable NEVoiceRoomInfo roomInfo) {

            }

            @Override
            public void onFailure(int code, @Nullable String msg) {}
            });
                  
  1. 主播调用 joinRoom接口加入房间。

示例代码如下:

 NEJoinVoiceRoomOptions options = new NEJoinVoiceRoomOptions();
    NEVoiceRoomKit.getInstance()
        .joinRoom(
            params,
            options,
            new NEVoiceRoomCallback<NEVoiceRoomInfo>() {

              @Override
              public void onFailure(int code, @Nullable String msg) {

              }

              @Override
              public void onSuccess(@Nullable NEVoiceRoomInfo roomInfo) {

              }
            });

  1. 调用 submitSeatRequest 上麦。

示例代码如下:

    NEVoiceRoomKit.getInstance().submitSeatRequest(1, true, new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onSuccess(@Nullable Unit unit) {
              
          }

          @Override
          public void onFailure(int code, @Nullable String msg) {

          }
      });

  1. 调用 addVoiceRoomListener 接口监听房间里的事件。

示例代码如下:

  NEVoiceRoomListener voiceRoomListener = new NEVoiceRoomListener() {
      @Override
      public void onMemberJoinRoom(@NonNull List<NEVoiceRoomMember> members) {
        
      }

      @Override
      public void onMemberLeaveRoom(@NonNull List<NEVoiceRoomMember> members) {

      }

      @Override
      public void onMemberJoinChatroom(@NonNull List<NEVoiceRoomMember> members) {

      }

      @Override
      public void onMemberLeaveChatroom(@NonNull List<NEVoiceRoomMember> members) {

      }

      @Override
      public void onRoomEnded(@NonNull NEVoiceRoomEndReason reason) {

      }

      @Override
      public void onRtcChannelError(int code) {

      }

      @Override
      public void onMemberAudioMuteChanged(@NonNull NEVoiceRoomMember member, boolean mute, @Nullable NEVoiceRoomMember operateBy) {

      }

      @Override
      public void onMemberAudioBanned(@NonNull NEVoiceRoomMember member, boolean banned) {

      }

      @Override
      public void onReceiveTextMessage(@NonNull NEVoiceRoomChatTextMessage message) {

      }

      @Override
      public void onSeatRequestSubmitted(int seatIndex, @NonNull String account) {

      }

      @Override
      public void onSeatRequestCancelled(int seatIndex, @NonNull String account) {

      }

      @Override
      public void onSeatRequestApproved(int seatIndex, @NonNull String account, @NonNull String operateBy, boolean isAutoAgree) {

      }

      @Override
      public void onSeatRequestRejected(int seatIndex, @NonNull String account, @NonNull String operateBy) {

      }

      @Override
      public void onSeatLeave(int seatIndex, @NonNull String account) {

      }

      @Override
      public void onSeatKicked(int seatIndex, @NonNull String account, @NonNull String operateBy) {

      }

      @Override
      public void onSeatInvitationAccepted(int seatIndex, @NonNull String account, boolean isAutoAgree) {

      }

      @Override
      public void onSeatListChanged(@NonNull List<NEVoiceRoomSeatItem> seatItems) {

      }

      @Override
      public void onAudioMixingStateChanged(int reason) {

      }

      @Override
      public void onAudioOutputDeviceChanged(@NonNull NEVoiceRoomAudioOutputDevice device) {

      }

      @Override
      public void onReceiveGift(@NonNull NEVoiceRoomGiftModel rewardMsg) {

      }

      @Override
      public void onReceiveBatchGift(@NonNull NEVoiceRoomBatchGiftModel giftModel) {

      }

      @Override
      public void onAudioEffectTimestampUpdate(long effectId, long timeStampMS) {

      }

      @Override
      public void onRtcLocalAudioVolumeIndication(int volume, boolean vadFlag) {

      }

      @Override
      public void onRtcRemoteAudioVolumeIndication(@NonNull List<? extends NEVoiceRoomMemberVolumeInfo> volumes, int totalVolume) {

      }

      @Override
      public void onAudioEffectFinished(int effectId) {

      }
    };
    NEVoiceRoomKit.getInstance().addVoiceRoomListener(voiceRoomListener);

  1. 收到加入成功的 onMemberJoinRoom 回调后,调用 unmuteMyAudio 方法开启本地音频采集。

示例代码如下:

NEVoiceRoomKit.getInstance()
        .unmuteMyAudio(
                new NEVoiceRoomCallback<Unit>() {
                    @Override
                    public void onSuccess(@Nullable Unit unit) {
                      
                    }

                    @Override
                    public void onFailure(int code, @Nullable String msg) {
                    }
                });

2. 观众进入房间

  1. 观众调用 joinRoom接口加入房间。

  2. 观众调用 addVoiceRoomListener 接口监听房间里的事件。

  3. 观众调用 muteMyAudio 方法关闭本地音频采集。

    等到上麦后,再开启本地音频采集。

3. 麦位管理

添加麦位事件监听

调用 addVoiceRoomListener接口,监听麦位相关的事件。

示例代码如下:

NEVoiceRoomListener voiceRoomListener = new NEVoiceRoomListener() {
    @Override
    public void onMemberJoinRoom(@NonNull List<NEVoiceRoomMember> members) {

    }

    @Override
    public void onMemberLeaveRoom(@NonNull List<NEVoiceRoomMember> members) {

    }

    @Override
    public void onRoomEnded(@NonNull NEVoiceRoomEndReason reason) {

    }

    @Override
    public void onRtcChannelError(int code) {

    }

    @Override
    public void onMemberAudioMuteChanged(@NonNull NEVoiceRoomMember member, boolean mute) {

    }

    @Override
    public void onMemberAudioBanned(@NonNull NEVoiceRoomMember member, boolean banned) {

    }

    @Override
    public void onReceiveTextMessage(@NonNull NEVoiceRoomChatTextMessage message) {

    }

    @Override
    public void onSeatRequestSubmitted(int seatIndex, @NonNull String account) {

    }

    @Override
    public void onSeatRequestCancelled(int seatIndex, @NonNull String account) {

    }

    @Override
    public void onSeatRequestApproved(int seatIndex, @NonNull String account, @NonNull String operateBy) {

    }

    @Override
    public void onSeatRequestRejected(int seatIndex, @NonNull String account, @NonNull String operateBy) {

    }

    @Override
    public void onSeatEnter(int seatIndex, @NonNull String account) {

    }

    @Override
    public void onSeatLeave(int seatIndex, @NonNull String account) {

    }

    @Override
    public void onSeatKicked(int seatIndex, @NonNull String account, @NonNull String operateBy) {

    }

    @Override
    public void onSeatOpened(int seatIndex) {

    }

    @Override
    public void onSeatClosed(int seatIndex) {

    }

    @Override
    public void onSeatInvitationReceived(int seatIndex, @NonNull String account, @NonNull String operateBy) {

    }

    @Override
    public void onSeatInvitationAccepted(int seatIndex, @NonNull String account, boolean isAutoAgree) {

    }

    @Override
    public void onSeatInvitationCancelled(int seatIndex, @NonNull String account, @NonNull String operateBy) {

    }

    @Override
    public void onSeatListChanged(@NonNull List<NEVoiceRoomSeatItem> seatItems) {

    }

    @Override
    public void onAudioMixingStateChanged(int reason) {

    }
  };
  NEVoiceRoomKit.getInstance().addVoiceRoomListener(voiceRoomListener);

主播邀请观众上麦

NEVoiceRoomKit.getInstance()
    .sendSeatInvitation(
        inviteIndex,
        member.account,
        new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onSuccess(@Nullable Unit unit) {
            
          }

          @Override
          public void onFailure(int code, @Nullable String msg) {

          }
        });

主播同意观众上麦

主播调用 approveSeatRequest 接口同意观众上麦。

NEVoiceRoomKit.getInstance()
    .approveSeatRequest(
        seat.getAccount(),
        new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onSuccess(@Nullable Unit unit) {
            
          }

          @Override
          public void onFailure(int code, @Nullable String msg) {
            
          }
        });

主播拒绝观众上麦

主播调用 rejectSeatRequest 接口拒绝观众上麦。

NEVoiceRoomKit.getInstance()
    .rejectSeatRequest(
        seat.getAccount(),
        new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onSuccess(@Nullable Unit unit) {
          
          }

          @Override
          public void onFailure(int code, @Nullable String msg) {
            
          }
        });

主播踢观众下麦

主播调用 kickSeat 接口踢观众下麦。

NEVoiceRoomKit.getInstance()
      .kickSeat(
          member.getAccount(),
          new NEVoiceRoomCallback<Unit>() {
            @Override
            public void onSuccess(@Nullable Unit unit) {
              
            }

            @Override
            public void onFailure(int code, @Nullable String msg) {
          
            }
          });

观众申请上麦

观众调用 submitSeatRequest 接口申请上麦。

NEVoiceRoomKit.getInstance()
    .submitSeatRequest(
        index,
        true,
        new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onFailure(int code, @Nullable String msg) {
      
          }

          @Override
          public void onSuccess(@Nullable Unit unit) {
        
          }
        });

观众取消申请上麦

观众调用 cancelSeatRequest 接口取消申请上麦。

NEVoiceRoomKit.getInstance()
    .cancelSeatRequest(
        new NEVoiceRoomCallback<Unit>() {
          @Override
          public void onFailure(int code, @Nullable String msg) {
          
          }

          @Override
          public void onSuccess(@Nullable Unit unit) {
      
          }
        });

观众主动下麦

观众调用 leaveSeat 接口下麦。

NEVoiceRoomKit.getInstance()
      .leaveSeat(
          new NEVoiceRoomCallback<Unit>() {
            @Override
            public void onFailure(int code, @Nullable String msg) {
            
            }

            @Override
            public void onSuccess(@Nullable Unit unit) {
              
            }
          });

4.聊天消息

  1. 调用 sendTextMessage 发送聊天室文本消息。

示例代码如下:

    NEVoiceRoomKit.getInstance()
        .sendTextMessage(
            content,
            new NEVoiceRoomCallback<Unit>() {
              @Override
              public void onSuccess(@Nullable Unit unit) {
               
              }

              @Override
              public void onFailure(int code, @Nullable String msg) {
               
              }
            });

5.离开房间

  1. 调用 leaveRoom 接口离开房间。

示例代码如下:

NEVoiceRoomKit.getInstance()
        .leaveRoom(
                new NEVoiceRoomCallback<Unit>() {
                    @Override
                    public void onSuccess(@Nullable Unit unit) {
                  
                    }

                    @Override
                    public void onFailure(int code, @Nullable String msg) {
                    
                    }
                });
  1. 离开房间成功后,会触发 NERoomListener.onMemberLeaveRoom 回调,通知房间内所有成员。

  2. 主播调用 endRoom 接口删除房间。

    示例代码如下:

    NEVoiceRoomKit.getInstance()
                .endRoom(
                        new NEVoiceRoomCallback<Unit>() {
                            @Override
                            public void onSuccess(@Nullable Unit unit) {
                    
                            }
    
                            @Override
                            public void onFailure(int code, @Nullable String msg) {
                              
                            }
                        });
    
  3. 删除房间成功后,会触发 NERoomListener 协议中的 onRoomEnded 回调方法。

进阶功能

伴音

  1. 调用 NEVoiceRoomKitstartAudioMixing 方法播放伴音。

NERoomCreateAudioMixingOption 参数说明如下表所示。

参数 类型 描述
path String 待播放的音乐文件的绝对路径或 URL 地址,支持本地 SD 卡中的绝对路径或 URL 地址
loopCount int 伴音循环播放的次数。1:(默认)播放一次。≤ 0:无限循环播放
sendEnabled boolean 是否将伴音发送远端,默认为 true,即远端用户可以听到该伴音。
sendVolume int 音乐文件的发送音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
playbackEnabled boolean 是否本地播放伴音。默认为 true,即本地用户可以听到该伴音。
playbackVolume int 音乐文件的播放音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
startTimeStamp long 音乐文件开始播放的时间,UTC 时间戳,即从1970 年 1 月 1 日 0 点 0 分 0 秒开始到事件发生时的毫秒数。默认值为 0,表示立即播放。
sendWithAudioType NERoomRtcAudioStreamType 伴音跟随音频主流还是辅流,默认跟随主流。
  • NERtcAudioStreamTypeMain:伴音跟随主流
  • NERtcAudioStreamTypeSub:伴音跟随辅流
  1. 调用 setAudioMixingVolume 设置伴音的音量。

  2. 在离开房间前调用 stopAudioMixing 结束伴音。

示例代码如下:

String path = audioMixingFilePaths[audioMixingIndex];
NEVoiceRoomCreateAudioMixingOption option =
    new NEVoiceRoomCreateAudioMixingOption(
        path, 1, true, audioMixingVolume, true, audioMixingVolume);
NEVoiceRoomKit.getInstance().startAudioMixing(option);

// 停止音效
NEVoiceRoomKit.getInstance().stopAudioMixing();

音效

  1. 调用 NEVoiceRoomKitplayEffect 方法播放音效。

    NERoomCreateAudioEffectOption 参数说明如下表所示。

    参数 类型 描述
    path String 待播放的音乐文件的绝对路径或 URL 地址,支持本地 SD 卡中的绝对路径或 URL 地址
    loopCount int 音效循环播放的次数。1:(默认)播放一次。≤ 0:无限循环播放
    sendEnabled boolean 是否将音效发送远端,默认为 true,即远端用户可以听到该音效。
    sendVolume int 音效文件的发送音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    playbackEnabled boolean 是否本地播放音效。默认为 true,即本地用户可以听到该音效。
    playbackVolume int 音乐文件的播放音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    startTimeStamp long 音乐文件开始播放的时间,UTC 时间戳,即从1970 年 1 月 1 日 0 点 0 分 0 秒开始到事件发生时的毫秒数。默认值为 0,表示立即播放。
    sendWithAudioType NERoomRtcAudioStreamType 伴音跟随音频主流还是辅流,默认跟随主流。
    • NERtcAudioStreamTypeMain:伴音跟随主流
    • NERtcAudioStreamTypeSub:伴音跟随辅流
  2. 调用 setEffectVolume 方法设置音效的音量。

  3. 在离开房间前,调用 stopAllEffect 方法停止播放所有音效文件。

示例代码如下:

String path = effectPaths[index];
int effectId = effectIndexToEffectId(index);
NEVoiceRoomCreateAudioEffectOption option =
    new NEVoiceRoomCreateAudioEffectOption(path, 1, true, effectVolume, true, effectVolume);
NEVoiceRoomKit.getInstance().playEffect(effectId, option);

耳返

  1. 调用 enableEarback 开启耳返。
     NEVoiceRoomKit.getInstance().enableEarback(volume);
    

    开启耳返功能后,必须连接上耳机或耳麦,才能正常使用耳返功能。

  2. 调用 disableEarback 关闭耳返。
     NEVoiceRoomKit.getInstance().disableEarback();
    

发送和接收礼物

  1. 观众调用 NEVoiceRoomKitsendBatchGift 接口发送礼物。

    参数说明如下:

    参数 类型 描述
    giftId Int 礼物 ID,礼物 ID 由业务服务器自行维护和下发。
    giftCount Int 给单个对象赠送的礼物数量,取值范围为1 ~ 1314。
    如果礼物赠送对象为多人,则送出的礼物总数为“礼物数量 x 赠送对象数量”。
    userUuids List 礼物赠送对象的用户 ID 的集合,只支持给主播和连麦者赠送礼物。
    userUuid 是您的应用服务器向 NERoom 服务器申请创建账号时,返回的账号,具体请参见创建账号
    callback NEVoiceRoomCallback? = nil 回调。

    示例代码如下:

    NEVoiceRoomKit.getInstance()
                        .sendBatchGift(
                            giftId,
                            giftCount,
                            userUuids,
                            new NEVoiceRoomCallback<Unit>() {
                                @Override
                                public void onSuccess(@Nullable Unit unit) {}
    
                                @Override
                                public void onFailure(int code, @Nullable String msg) {
                                
                                }
                            })
    
  2. 接收礼物。

    监听 onReceiveBatchGift 回调。当收到礼物时,会触发该回调。

    示例代码如下:

        @Override
            public void onReceiveBatchGift(@NonNull NEVoiceRoomBatchGiftModel giftModel) {
            // 收到批量礼物回调
            }
    

设置悬浮小窗(浮窗)模式

当您的手机需要操作其他界面时,您可以单击右上角最小化按钮,将语聊房窗口设置为悬浮小窗模式,使任务切换更便捷。

悬浮小窗时,系统并不会退出当前房间,后台继续运行语聊房。

小窗.png

实现思路如下:

  1. 小窗播放需要先获取系统悬浮窗权限,再通过 WindowManager.addView 方法添加小窗视图。
  2. 小窗随手指移动、贴边功能、点击事件,请参考 FloatView 类的 onTouchEvent 方法。

具体实现方法请参考语聊房示例项目源码。示例项目源码中的相关说明如下:

  • FloatPlayLayout:自定义悬浮小窗的界面视图。
  • FloatPlayManager:控制悬浮小窗展示逻辑。
  • FloatWindowPermissionManager:悬浮窗权限管理。

展示悬浮小窗

示例代码如下:

FloatPlayManager.getInstance().startFloatPlay();

隐藏悬浮小窗

示例代码如下:

FloatPlayManager.getInstance().stopFloatPlay();

音频波谱

主播、连麦者说话时,相应的麦位上会展示音频波谱,以便观众识别当前说话者。

实现方法如下:

  1. 监听 NEVoiceRoomKitonRtcAudioVolumeIndication 回调,成员说话时会触发该回调。
  2. 在回调方法中获取音量值 volumes
  3. 根据 volumes 音量值,使用 LottieAnimationView三方库加载本地动画。

详细的示例代码请参见语聊房示例项目源码

此文档是否对你有帮助?
有帮助
去反馈
  • 开发环境要求
  • 前提条件
  • 方案架构
  • API调用时序图
  • 示例项目源码
  • 集成 VoiceRoom 组件
  • 步骤1 集成 VoiceRoom 组件
  • 步骤2 配置权限
  • 初始化组件
  • 登录鉴权
  • 实现语聊房
  • 1. 主播开播
  • 2. 观众进入房间
  • 3. 麦位管理
  • 添加麦位事件监听
  • 主播邀请观众上麦
  • 主播同意观众上麦
  • 主播拒绝观众上麦
  • 主播踢观众下麦
  • 观众申请上麦
  • 观众取消申请上麦
  • 观众主动下麦
  • 4.聊天消息
  • 5.离开房间
  • 进阶功能
  • 伴音
  • 音效
  • 耳返
  • 发送和接收礼物
  • 设置悬浮小窗(浮窗)模式
  • 音频波谱