You need to enable JavaScript to run this app.
导航

场景搭建(Android)

最近更新时间2023.12.13 16:13:04

首次发布时间2022.11.15 15:26:04

SDK集成

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

  1. RTC SDK总体接入流程,详细步骤请参看 RTC服务开通指南

alt

  1. HIFIVE 音乐开放平台 SDK 接入流程,详细步骤请参看 HIFIVE 集成文档

整体实现流程

整体业务流程图

alt

核心功能实现

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

创建/加入房间

时序图

alt

示例代码

/**
 * 加入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);
}
private 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) {
    }
}

歌词同步

时序图

alt

示例代码

/**
 * 开始演唱。在歌词/歌曲下载完成,收到开始演唱广播后执行。
 * @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);
}
/**
 * 音乐文件播放状态改变回调
 */
@Override
public void onAudioMixingStateChanged(int mixId, AudioMixingState state, AudioMixingError error) {
    super.onAudioMixingStateChanged(mixId, state, error);
    if (state == AudioMixingState.AUDIO_MIXING_STATE_FINISHED) {
        // 歌曲播放结束
    }
}

歌曲控制台

alt

alt

示例代码

/**
 * 原唱/伴奏切换,需要音乐素材支持右声道伴奏,左声道原唱
 * @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);
}

核心功能 API 与回调参考

API

功能点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