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

使用混音功能

最近更新时间2024.02.28 18:03:31

首次发布时间2021.07.18 15:06:55

在用户使用 “一起看”、“一起听” 等互动娱乐类应用时,如果需要在通话过程中播放音乐文件等,而且让房间内的其他成员也听到声音,需要使用音乐播放类。
播放音乐指的是时长较长的音频或 PCM 数据,例如,伴奏、背景音乐等。同一时间,只能播放 4 个音乐文件。

一般来说,时长小于 20 s 的音频为音效,应使用音效播放器接口,参考 播放音效

前提条件

你已经集成 RTC SDK,实现了基本的音视频通话。
支持音乐播放的 SDK 详见API 及回调

功能实现

参考以下顺序,调用 API 实现此功能:

调用目标非 PCM 音频文件PCM 音频文件
初始化getMediaPlayergetMediaPlayer
设置回调句柄setEventHandlersetEventHandler
启动openopenWithCustomSource
开始播放startpushExternalAudioFrame
结束stopstop

创建引擎

创建音视频引擎类后,你可以通过调用 getMediaPlayer,传入播放器 ID 创建一个音乐播放器类。

如果你需要将音频发送到远端,还需要加入房间并发布音频流,参考 构建 RTC 应用 获取详细步骤。

// 创建引擎
rtcVideo = RTCVideo.createRTCVideo(this, Constants.APP_ID, rtcVideoEventHandler, null, null);
// 开启本地音频采集
rtcVideo.startAudioCapture();
//播放非 PCM 文件
mediaPlayer = rtcVideo.getMediaPlayer(PLAYER_ID_1);

设置回调

你可以通过回调感知音乐的播放状态和播放位置。

// handler 建议使用强引用
mediaPlayer.setEventHandler(playerEventHandler);

播放非 PCM 音频文件

对同一个音频文件进行操作时,混音 ID 应保持一致

打开音乐文件

private void openMedia(String filePath) {
    MediaPlayerConfig playerConfig = new MediaPlayerConfig();
    playerConfig.startPos = 0;
	// autoPlay=true时自动播放,无需再调用 start 接口
	// autoPlay=false时,不自动播放,需要调用 start 接口
    playerConfig.autoPlay = false;
    playerConfig.playCount = 1; // 播放次数
    playerConfig.type = AudioMixingType.AUDIO_MIXING_TYPE_PLAYOUT_AND_PUBLISH;
    playerConfig.callbackOnProgressInterval = 500;
    mediaPlayer.open(filePath, playerConfig);
}

手动播放

已经调用 open,且 auto_play = false 时,需要调用 start 播放音乐。

mediaPlayer.start()

停止播放

如果你需要在播放中主动终止播放,可以调用 stop 方法。

mediaPlayer.stop()

暂停/恢复音乐

mediaPlayer.pause()
mediaPlayer.resume()

获取和设置音乐属性

所有的混音相关设置都必须在开始播放以后,停止播放之前进行,否则不生效,包括但不限于设置播放音量,设置播放起始位置等。

// 获取音量
float volume = mediaPlayer.getVolume();
// 设置音量
mediaPlayer.setVolume(value, type);

// 文件总时长,单位 ms
int totalTime = mediaPlayer.getTotalDuration();
// 播放时长,单位 ms
int playbackDuration = mediaPlayer.getPlaybackDuration();
// 播放位置,单位 ms
int currentPosition = mediaPlayer.getPosition();
// 设置起播位置,单位 ms
mediaPlayer.setPosition(value);

// 音轨
int trackCount = mediaPlayer.getAudioTrackCount();
// 选择播放指定的音轨音乐
mediaPlayer.selectAudioTrack(track);

// 播放速度,单位:%,取值范围为[50, 200],默认值为100
mediaPlayer.setPlaybackSpeed(speed);

播放 PCM 文件

启动混音

在调用 openWithCustomSource 启动混音前,可以进行初始化设置,包括是否自动播放、播放次数等。

private void startPlayPCM() {
    openFile(pcmPath);

    MediaPlayerCustomSource source = new MediaPlayerCustomSource();
    source.mode = MediaPlayerCustomSourceMode.PUSH;
    source.type = MediaPlayerCustomSourceStreamType.RAW;
    source.provider = null;

    MediaPlayerConfig playerConfig = new MediaPlayerConfig();
    playerConfig.startPos = 0;
	// autoPlay=true时自动播放,无需再调用 start 接口
	// autoPlay=false时,不自动播放,需要调用 start 接口
    playerConfig.autoPlay = true;
    playerConfig.playCount = 1;
    playerConfig.type = AudioMixingType.AUDIO_MIXING_TYPE_PLAYOUT_AND_PUBLISH;
    playerConfig.callbackOnProgressInterval = 500;

    pcmPlayer.openWithCustomSource(source, playerConfig);
    startPushPCM();
}

播放混音

调用 pushExternalAudioFrame 向 RTC 推送音频数据前,你需要按照 RTC SDK 要求对数据进行处理。以下代码片段以示例项目中提供的 PCM 音频文件为例,说明数据的格式要求。

Runnable pushAudioFrameTask = new Runnable() {
    @Override
    public void run() {
        // 每10ms的数据大小
        int size = 16 * 10;
        if (isFirstPush) {
            // 建议第一次时传入 200ms 的缓冲数据,避免噪音
            size = size * 20;
            isFirstPush = false;
        }
        ByteBuffer pushBuffer = ByteBuffer.allocate(size * 2);
        AudioFrame audioFrame = new AudioFrame();
        audioFrame.channel = AudioChannel.AUDIO_CHANNEL_MONO;
        audioFrame.sampleRate = AudioSampleRate.AUDIO_SAMPLE_RATE_16000;
        audioFrame.samples = size;

        int nRead = 0;
        if (fileData != null) {
            nRead = Integer.min(size * 2, fileDataBufferSize - fileDataOffset);
            pushBuffer.put(fileData, fileDataOffset, nRead);
            fileDataOffset += nRead;
        }
        Log.i(TAG, "offset:" + fileDataOffset + " read:" + nRead);
        if (nRead == 0) {
            stopPlayPCM();
            return;
        }
        audioFrame.buffer = pushBuffer.array();
        pcmPlayer.pushExternalAudioFrame(audioFrame);
    }
};

结束混音

如果你需要在播放中主动终止播放,可以调用 stop 方法。

pcmPlayer.stop();

调整混音音量

音量设置必须在开始播放以后,停止播放之前进行,否则不生效。
移动端可以通过 setVolumeAll 接口,批量设置全部混音音量。PC端只能通过 setVolume 接口逐个指定混音音量。

pcmPlayer.setVolume(volume, AudioMixingType.AUDIO_MIXING_TYPE_PLAYOUT_AND_PUBLISH);

示例项目

API 参考

说明:表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。

平台AndroidiOSmacOSWindowsLinuxELectronFlutterWeb

初始化音乐管理类

getMediaPlayer

getMediaPlayer

getMediaPlayer

getMediaPlayer

getMediaPlayer

getMediaPlayer

getMediaPlayer

getAudioMixingManager

音乐混音管理类IMediaPlayerByteRTCMediaPlayerByteRTCMediaPlayerIMediaPlayerMediaPlayerRTCMediaPlayerRTCMediaPlayerAudioMixingManager
音乐播放器状态回调onMediaPlayerStateChangedonMediaPlayerStateChanged:state:error:onMediaPlayerStateChanged:state:error:onMediaPlayerStateChangedonMediaPlayerStateChangedonMediaPlayerStateChangedonMediaPlayerStateChanged
音乐播放进度回调onMediaPlayerPlayingProgressonMediaPlayerPlayingProgress:progress:onMediaPlayerPlayingProgress:progress:onMediaPlayerPlayingProgressonMediaPlayerPlayingProgressonMediaPlayerPlayingProgressonMediaPlayerPlayingProgress

变更日志

  1. 自客户端 SDK 3.32 起,支持对音乐文件的声道进行设置。

  2. 自客户端 SDK 3.36 起,全平台支持在线音频文件混音。

  3. 自客户端 SDK 3.38 起,支持调整音视频通话中使用的音频文件的播放速度。

  4. 自客户端 SDK 3.45.4 起,支持获取混音音频文件的实际播放时长,即歌曲不受停止、跳转、倍速、卡顿影响的播放时长。

  5. 自客户端 SDK 3.52 起,支持混音播放 24kHz 的 mp3 文件。3.52 之前版本仅支持以下采样率的音频文件:8kHz、16kHz、22.05kHz、32kHz、44.1kHz、48kHz、64kHz、96kHz、192kHz。

  6. 自客户端 SDK 3.54 起,Native 平台废弃原有的混音类,分为音效混音和音乐混音,支持分别控制。