Android SDK集成

本文介绍K歌房多人合唱模式Android SDK集成的代码示例及集成说明。

功能时序图

使用自研播放器播放音乐

image.png

使用ARTC解码和播放音乐

如果您需要使用实时音视频ARTC解码和播放音乐,请提交工单咨询。关于如何提交工单,请参见联系我们

主播创建房间

mAliRtcEngine.setChannelProfile(AliRTCSdkInteractiveLive);
mAliRtcEngine.setClientRole(AliRTCSdkInteractive);
/* 使用高音质和ktv场景 */
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneKtvMode);
//auto pub
mAliRtcEngine.publishLocalAudioStream(true);

/* 设置回调的监听 */
mAliRtcEngine.setRtcEngineEventListener(this);

//auto sub
mAliRtcEngine.setDefaultSubscribeAllRemoteAudioStreams(true);
mAliRtcEngine.subscribeAllRemoteAudioStreams(true);
mAliRtcEngine.setAudioOnlyMode(true);

mAliRtcEngine.enableSpeakerphone(true);
JSONObject tokenv2 = new JSONObject();
tokenv2.put("appid", userInfo.appId);
tokenv2.put("channelid", userInfo.channelId);
tokenv2.put("userid", userInfo.userId);
tokenv2.put("nonce", userInfo.nonce);
tokenv2.put("timestamp", userInfo.timestamp);
tokenv2.put("gslb",userInfo.gslb);
tokenv2.put("token", userInfo.token);
String base64TokenV2 = Base64.encodeToString(JSON.toJSONBytes(tokenv2),Base64.NO_WRAP);
/* 入会 */
mAliRtcEngine.joinChannel(base64TokenV2, null, null, mUsername);
/* 打开datachannel 用于接受歌曲进度 */
String param = "\"data\":{\"enablePubDataChannel\":true" + ",\"enableSubDataChannel\":true}";
param = "{" + param + "}";
mAliRtcEngine.setParameter(param);

观众进入房间

mAliRtcEngine.setChannelProfile(AliRTCSdkInteractiveLive);
mAliRtcEngine.setClientRole(AliRTCSdkLive);
/* 使用高音质和ktv场景 */
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneKtvMode);
//auto pub
mAliRtcEngine.publishLocalAudioStream(true);

/* 设置回调的监听 */
mAliRtcEngine.setRtcEngineEventListener(this);

//auto sub
mAliRtcEngine.setDefaultSubscribeAllRemoteAudioStreams(true);
mAliRtcEngine.subscribeAllRemoteAudioStreams(true);
/* 观众需要订阅伴奏流 */
mAliRtcEngine.subscribeAllRemoteDualAudioStreams(true);

mAliRtcEngine.setAudioOnlyMode(true);

mAliRtcEngine.enableSpeakerphone(true);
JSONObject tokenv2 = new JSONObject();
tokenv2.put("appid", userInfo.appId);
tokenv2.put("channelid", userInfo.channelId);
tokenv2.put("userid", userInfo.userId);
tokenv2.put("nonce", userInfo.nonce);
tokenv2.put("timestamp", userInfo.timestamp);
tokenv2.put("gslb",userInfo.gslb);
tokenv2.put("token", userInfo.token);
String base64TokenV2 = Base64.encodeToString(JSON.toJSONBytes(tokenv2),Base64.NO_WRAP);
/* 入会 */
mAliRtcEngine.joinChannel(base64TokenV2, null, null, mUsername);
/* 打开datachannel 用于接受歌曲进度 */
String param = "\"data\":{\"enablePubDataChannel\":true" + ",\"enableSubDataChannel\":true}";
param = "{" + param + "}";
mAliRtcEngine.setParameter(param);

主播点歌

  1. 添加伴奏流并创建pcm输入。

    mAliRtcEngine.publishLocalDualAudioStream(true);
    AliRtcEngine.AliRtcExternalAudioStreamConfig config = new AliRtcEngine.AliRtcExternalAudioStreamConfig();
    config.sampleRate = sampleRate;
    config.channels = channels;
    /* 伴奏音乐本地播放的音量,如果需要rtc sdk来实现播放,可以设置该值 */
    config.playoutVolume = 60;
    config.publishVolume = 100;
    config.publishStream = 1; // 指定通过伴奏流推送
    int externalAudioStreamId = aliRtcEngine.addExternalAudioStream(config);
  2. 准备好物料文件之后,持续解码输入pcm数据。

    /* ... 持续送入pcm数据... */
    AliRtcEngine.AliRtcAudioFrame sample = new AliRtcEngine.AliRtcAudioFrame();
    sample.data = buffer;
    sample.numSamples = numSamples;
    sample.numChannels = channels;
    sample.sampleRate = sampleRate;
    sample.bytesPerSample = bytesPerSample;
    int ret = aliRtcEngine.pushExternalAudioStreamRawData(externalAudioStreamId, sample);
  3. 输入pcm数据的同时,更新进度。

    AliRtcEngine.AliRtcDataChannelMsg msg = new AliRtcEngine.AliRtcDataChannelMsg();
    msg.type = AliRtcEngine.AliRtcDataMsgType.AliEngineDataMsgMusicProgress;
    msg.networkTime = mAliRtcEngine.getNetworkTime();
    msg.progress = progress;
    
    mAliRtcEngine.sendDataChannelMsg(msg);

观众获取进度更新歌词

public void onDataChannelMessage(String uid, AliRtcEngine.AliRtcDataChannelMsg controlMsg) {
    super.onDataChannelMessage(uid, controlMsg);
    Log.d(TAG, "datachannel type=" + controlMsg.type + ", time=" + controlMsg.networkTime + ", progress=" + controlMsg.progress);
    /* 更新进度到controlMsg.progress */
}

观众上麦成为参唱者

/* 参与演唱不需要订阅伴奏流,本地播放 */
mAliRtcEngine.subscribeAllRemoteDualAudioStreams(false);
mAliRtcEngine.setClientRole(AliRTCSdkInteractive);

参唱者接受进度更新播放位置

public void onDataChannelMessage(String uid, AliRtcEngine.AliRtcDataChannelMsg controlMsg) {
    super.onDataChannelMessage(uid, controlMsg);
    Log.d(TAG, "datachannel type=" + controlMsg.type + ", time=" + controlMsg.networkTime + ", progress=" + controlMsg.progress);
    /* 进度需要加上 传输耗时,做到伴奏精准同步 */
    long div = mAliRtcEngine.getNetworkTime() - controlMsg.networkTime;
    long progress = controlMsg.progress + div;
    /* 更新歌曲播放进度到progress */
}

参唱者下麦成为观众

/* 观众需要订阅远端的流来播放伴奏 */
mAliRtcEngine.subscribeAllRemoteDualAudioStreams(true);
mAliRtcEngine.setClientRole(AliRTCSdkLive);

主播切歌

mAliRtcEngine.removeExternalAudioStream(externalAudioStreamId);
/* 停止伴奏流 */
mAliRtcEngine.publishLocalDualAudioStream(true);
/* 停止歌曲解码 、IM通知其他人 */