为了保证最佳体验效果,本场景需要集成火山引擎的 RTC SDK 以及 HIFIVE 音乐开放平台的SDK,您需要在 RTC、HIFIVE的控制台开通服务,相应开通指南如下:


当前仅提供了你已通过其他渠道获取音乐文件时,实现 KTV 场景的参考实现。RTC 也提供从曲库接入到 KTV 场景的完整能力,如果希望获取参考文档,请咨询技术支持。

/**
* 加入RTC房间并初始化参数
* @param token 加入 RTC 房间的 token
* @param roomId 加入 RTC 房间的 id
* @param userId 加入 RTC 房间的 用户id
* @param isHost true 是业务上主播角色;false 是业务上观众角色
*/
public void joinRTCRoom(String token, String roomId, String userId, boolean isHost) {
// 初始化 RTCVideo 对象
mRTCVideo = RTCVideo.createRTCVideo(applicationContext, appId, mIRTCVideoEventHandler, null, null);
// 初始化 RTCRoom 对象
mRTCRoom = mRTCVideo.createRTCRoom(roomId);
mRTCRoom.setRTCRoomEventHandler(mIRTCRoomEventHandler);
// 设置音频场景类型 Music
mRTCVideo.setAudioScenario(AudioScenarioType.AUDIO_SCENARIO_MUSIC);
// 设置音频双声道音乐音质
mRTCVideo.setAudioProfile(AudioProfileType.AUDIO_PROFILE_HD);
// 设置主播为可见,观众为隐身
mRTCRoom.setUserVisibility(isHost);
// 加入房间时主播需要开启麦克风,观众需要关闭麦克风
if (isHost) {
mRTCVideo.startAudioCapture();
} else {
mRTCVideo.stopAudioCapture();
}
// 设置音频路由模式
mRTCVideo.setDefaultAudioRoute(AudioRoute.AUDIO_ROUTE_SPEAKERPHONE);
// 开启发言者音量监听
AudioPropertiesConfig audioPropertiesConfig = new AudioPropertiesConfig(300);
mRTCVideo.enableAudioPropertiesReport(audioPropertiesConfig);
// 加入房间,开始连麦,需要申请AppId和Token
UserInfo userInfo = new UserInfo(userId, null);
RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_KTV,
true, true, true);
mRTCRoom.joinRoom(token, userInfo, roomConfig);
}
Javaprivate final IRTCVideoEventHandler mIRTCVideoEventHandler = new IRTCVideoEventHandler() {
/**
* 本地用户音量回调
*/
@Override
public void onLocalAudioPropertiesReport(LocalAudioPropertiesInfo[] audioPropertiesInfos) {
super.onLocalAudioPropertiesReport(audioPropertiesInfos);
}
/**
* 远端用户音量回调
*/
@Override
public void onRemoteAudioPropertiesReport(RemoteAudioPropertiesInfo[] audioPropertiesInfos, int totalRemoteVolume) {
super.onRemoteAudioPropertiesReport(audioPropertiesInfos, totalRemoteVolume);
}
};
private final IRTCRoomEventHandler mIRTCRoomEventHandler = new IRTCRoomEventHandler() {
/**
* 收到 RTC 加入房间结果
*/
@Override
public void onRoomStateChanged(String roomId, String uid, int state, String extraInfo) {
}
}
Java
/**
* 开始演唱。在歌词/歌曲下载完成,收到开始演唱广播后执行。
* @param filePath 歌曲的文件路径
*/
public void startStartSing(String filePath) {
// 设置歌曲本地播放和推送到远端
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
AudioMixingConfig audioMixingConfig = new AudioMixingConfig(AUDIO_MIXING_TYPE_PLAYOUT_AND_PUBLISH, 1);
// 开始播放歌曲
audioMixingManager.startAudioMixing(audioMixingId, filePath, audioMixingConfig);
audioMixingManager.setAudioMixingProgressInterval(audioMixingId, 100);
}
/**
* 收到本地歌曲播放进度回调
* @param mixId 混音ID
* @param progress 歌曲播放进度,单位为毫秒
*/
@Override
public void onAudioMixingPlayingProgress(int mixId, long progress) {
super.onAudioMixingPlayingProgress(mixId, progress);
// 如果是演唱者
if (isSinger) {
// 刷新本地歌词进度
syncLocalLyricsProgress(progress);
// 发送音频流同步信息
String progressStr = String.valueOf(progress);
StreamSycnInfoConfig streamSycnInfoConfig = new StreamSycnInfoConfig(
StreamIndex.STREAM_INDEX_MAIN,
3,
StreamSycnInfoConfig.SyncInfoStreamType.SYNC_INFO_STREAM_TYPE_AUDIO
);
mRTCVideo.sendStreamSyncInfo(progressStr.getBytes(StandardCharsets.UTF_8), streamSycnInfoConfig);
}
}
/**
* 收到音频同步信息
* @param streamKey 远端流信息
* @param streamType 媒体流类型
* @param data 消息内容
*/
@Override
public void onStreamSyncInfoReceived(RemoteStreamKey streamKey, StreamSycnInfoConfig.SyncInfoStreamType streamType, ByteBuffer data) {
super.onStreamSyncInfoReceived(streamKey, streamType, data);
Charset charset = StandardCharsets.UTF_8;
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = null;
try {
charBuffer = decoder.decode(data);
} catch (CharacterCodingException e) {
}
String progressStr = charBuffer != null ? charBuffer.toString() : null;
long progress = Long.parseLong(progressStr);
// 观众刷新歌词进度
syncLocalLyricsProgress(progress);
}
Java/**
* 音乐文件播放状态改变回调
*/
@Override
public void onAudioMixingStateChanged(int mixId, AudioMixingState state, AudioMixingError error) {
super.onAudioMixingStateChanged(mixId, state, error);
if (state == AudioMixingState.AUDIO_MIXING_STATE_FINISHED) {
// 歌曲播放结束
}
}
Java

/**
* 原唱/伴奏切换,需要音乐素材支持右声道伴奏,左声道原唱
* @param isAccompaniment 是否为伴奏,YES 为伴奏,NO 为原唱
*/
public void switchAccompaniment(boolean isAccompaniment) {
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
AudioMixingDualMonoMode audioMixingDualMonoMode = isAccompaniment ? AUDIO_MIXING_DUAL_MONO_MODE_R : AUDIO_MIXING_DUAL_MONO_MODE_L;
audioMixingManager.setAudioMixingDualMonoMode(audioMixingId, audioMixingDualMonoMode);
}
/**
* 原唱/伴奏切换,需要音乐素材支持。通过切换音轨来实现切换原唱/伴奏
* @param audioTrackIndex 指定的播放音轨。
*/
public void setIsAccompaniment(int audioTrackIndex) {
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
audioMixingManager.selectAudioTrack(audioMixingId, audioTrackIndex);
}
/**
* 暂停混音播放
*/
public void pauseSinging() {
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
audioMixingManager.pauseAudioMixing(audioMixingId);
}
/**
* 恢复混音播放
*/
public void resumeSinging() {
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
audioMixingManager.resumeAudioMixing(audioMixingId);
}
/**
* 开启/关闭耳返
* @param isEnable YES 为开启耳返,NO 为关闭耳返
*/
public void enableEarMonitor(boolean isEnable) {
mRTCVideo.setEarMonitorMode(isEnable ? EarMonitorMode.EAR_MONITOR_MODE_ON : EarMonitorMode.EAR_MONITOR_MODE_OFF);
}
/**
* 设置耳返的音量
* @param volume 耳返音量
*/
public void setEarMonitorVolume(int volume) {
mRTCVideo.setEarMonitorVolume(volume);
}
/**
* 调节本地播放和远端混音的音量大小
* @param volume 混音音量
*/
public void setMusicVolume(int volume) {
IAudioMixingManager audioMixingManager = mRTCVideo.getAudioMixingManager();
audioMixingManager.setAudioMixingVolume(audioMixingId, volume, AUDIO_MIXING_TYPE_PLAYOUT_AND_PUBLISH);
}
/**
* 调节麦克风采集音量
* @param volume 麦克风采集音量
*/
public void setRecordingVolume(int volume) {
mRTCVideo.setCaptureVolume(StreamIndex.STREAM_INDEX_MAIN, volume);
}
/**
* 设置混响特效类型
* @param reverbType 特效类型
*/
public void setVoiceReverbType(VoiceReverbType reverbType) {
mRTCVideo.setVoiceReverbType(reverbType);
}
Java| 功能点 | API |
|---|---|
| 创建 ByteRTCVideo 实例 | createRTCVideo |
| 创建 ByteRTCRoom 实例 | createRTCRoom: |
| 设置音频场景类型 | setAudioScenario: |
| 设置用户可见性 | setUserVisibility: |
| 开启内部音频采集 | startAudioCapture |
| 关闭内部音频采集 | stopAudioCapture |
| 设置当前音频播放路由 | setDefaultAudioRoute |
| 设置音质档位 | setAudioProfile: |
| 开启音量信息提示 | enableAudioPropertiesReport |
| 加入 RTC 房间 | joinRoom |
| 离开 RTC 房间 | leaveRoom |
| 销毁房间对象 | destroy |
| 在当前所在房间内发布本地通过摄像头/麦克风采集的媒体流 | publishStream |
| 停止将本地摄像头/麦克风采集的媒体流发布到当前所在房间中 | unpublishStream |
| 开启混音播放 | startAudioMixing |
| 关闭混音播放 | stopAudioMixing |
| 暂停混音播放 | pauseAudioMixing |
| 恢复混音播放 | resumeAudioMixing |
| 设置混音时音频文件播放进度回调的间隔 | setAudioMixingProgressInterval |
| 设置当前音频文件的声道模式 | setAudioMixingDualMonoMode |
| 发送音频流同步信息 | sendStreamSyncInfo |
| 设置混响特效类型 | setVoiceReverbType |
| 开启/关闭耳返功能 | setEarMonitorMode |
| 设置耳返的音量 | setEarMonitorVolume |
| 调节音频采集音量 | setCaptureVolume |
| 调节混音的音量大小 | setAudioMixingVolume |
| 功能点 | 回调 |
|---|---|
| 本地用户加入 RTC 回调 | onRoomStateChanged |
| 远端用户加入 RTC 回调 | onUserJoined |
| 本地用户音量回调 | onLocalAudioPropertiesReport |
| 远端用户音量回调 | onRemoteAudioPropertiesReport |
| 收到音频同步信息 | onStreamSyncInfoReceived |
| 音乐文件播放状态改变回调 | onAudioMixingStateChanged |
| 收到音乐文件播放进度回调 | onAudioMixingPlayingProgress |