本章教程,只支持
Electron
环境,非Web
端
当用户在 RTC 与白板的动态 PPT 同时使用时,可能会遇到以下问题:
为了解决这些问题,2.9.14 的白板内置了用于混音的 RTC 接口,用户在根据本章内容进行实现后可以避免这些问题。
如果用户使用的 RTC 提供商不支持混音本章内容将会无效
用户需要实现 AudioMixerImpl 类,该类用于桥接 whiteboard sdk 与用户引用的 RTC 客户端。
PPT 内部在触发播放事件前会调用 AudioMixerBridge 接口方法,通过用户的实现类调用到 RTC 的混音相关方法。
AudioMixerImpl 的实现例子如下:
class AudioMixerImpl implements RTCClient {
private readonly rtcEngine: AgoraSdk;
public startCallback?: (state: number, errorCode: number) => void;
public stopCallback?: (state: number, errorCode: number) => void;
public constructor(rtcEngine: AgoraSdk) {
this.rtcEngine = rtcEngine;
}
public startAudioMixing(
filePath: string,
loopback: boolean,
replace: boolean,
cycle: number,
callback?: (state: number, errorCode: number) => void,
): number {
this.startCallback = callback;
// 目前发现,如果 filePath 为线上资源时,有一定概率播放时没有声音。
// 请提前使用 动态 ppt 资源包下载到本地,并在这里进行替换
return this.rtcEngine.startAudioMixing(
filePath,
loopback,
replace,
cycle,
);
}
public stopAudioMixing(callback?: (state: number, errorCode: number) => void): number {
this.stopCallback = callback;
return this.rtcEngine.stopAudioMixing();
}
public pauseAudioMixing(): number {
return this.rtcEngine.pauseAudioMixing();
}
public resumeAudioMixing(): number {
return this.rtcEngine.resumeAudioMixing();
}
public setAudioMixingPosition(position: number): number {
// 如果 position 为 0,则必须跳过,否则将不会发出声音
// 因为音频流可能仍在加载,所以如果将其设置为 0,则会在 agora-electron-sdk 中引起意外情况
if (position !== 0) {
return this.rtcEngine.setAudioMixingPosition(position);
}
return 0;
}
}
在 2.9.14 后的 white sdk 初始化方法中多了一个可选参数 pptParams.rtcClient
。用户如果要使用 RTC 混音功能需要在初始化 sdk 前将 AudioMixerImpl 接口实现传入到该方法中:
// 如果用户需要用到 rtc 混音功能来解决回声和声音抑制问题,那么必须要在 white-web-sdk 之前初始化 rtcEngine
// AudioMixerImpl 在传入 sdk 后,ppt 内的音视频就全部使用 rtc 混音的方式播放
const audioMixer = new AudioMixerImpl(rtcEngine);
const whiteWebSdk = new WhiteWebSdk({
// ...
pptParams: {
rtcClient: audioMixer,
},
});
RTC 客户端需要有混音状态回调提示,在该回调方法中调用 sdk 中的混音状态变化方法来通知 PPT 是否该进行视频播放。
如果 RTC 客户端没有相关回调会造成 PPT 的视频音画不同步问题。
enum audioMixingStateChangedState {
// 正在播放混音文件
Start = 710,
// 正在暂停混音文件
Stop = 713,
}
const audioMixingStateChanged = (state: number, errorCode: number): void => {
if (audioMixer === undefined) {
return;
}
switch (state) {
case audioMixingStateChangedState.Stop: {
if (audioMixer.stopCallback) {
audioMixer.stopCallback(state, errorCode);
}
break;
}
case audioMixingStateChangedState.Start: {
if (audioMixer.startCallback) {
audioMixer.startCallback(state, errorCode);
}
break;
}
default: {
if (audioMixer.startCallback) {
audioMixer.startCallback(state, errorCode);
} else if (audioMixer.stopCallback) {
audioMixer.stopCallback(state, errorCode);
}
break;
}
}
}
rtcEngine.on("audioMixingStateChanged", audioMixingStateChanged);
// 组件卸载时,必须 remove audioMixingStateChanged,否则将会报错
// rtcEngine.off("audioMixingStateChanged", audioMixingStateChanged);
startAudioMixing
里进行替换 filePath
audioMixingStateChanged
事件回收,否则再次进入教室内时,就会报错,无法让视频播放