在视频通话应用中集成音量功能(例如,控制用户的音量、提示说话者其麦克风处于静音状态以及使用音效)是一项费时费力的活儿,如果你也有这个苦恼,不妨看看本文,我们手把手教你如何添加这些功能。
把 SDK 和复杂的 React 集成并充分利用 React 的功能有一定难度。在下面这个教程里,我们会写一个简易的 React 应用,然后基于这个简易的 React 应用给一个基础视频通话应用添加上述功能。
可以用声网 SDK 的 React wrapper 来创建一个基础视频通话应用。(本文没有使用 React wrapper,感兴趣的童鞋可以自己尝试一下哦~)
大家可以点击这里测试搭建好的应用的实时 demo,也可以点击这里查看 Github 资源库。
前期准备
- 了解 React 的基础知识
- 声网 RTC
注册声网
在使用声网 SDK 之前,我们需要获取一个 App ID(点击这里查看如何获取声网 App ID)。
注意: 本指南没有执行令牌验证,但我们建议所有处于生产环境的 RTE 应用都使用令牌验证。想了解更多关于声网Agora 平台上基于令牌进行身份验证的信息,请查看 视频通话 - 文档中心 - 声网。
代码
首先,用这个仓库作为模板,创建一个标准版声网Agora RTC 多人通话应用。
应用架构
这个应用包含下列组件:
- 全局容器:包含下列所有组件;
- 视频组件:控制每位用户的视频传送;
- 视频组件:控制特定用户的视频传送;
- 控件组件(包含在每个视频组件里):包括音视频静音、一个调整用户音量的 input、和供客户端使用的退出通话按钮等选项。
静音提示弹框
静音提示弹框是用户在静音状态下说话时显示的。我们基于 user.audio 状态的改变在控件组件中使用 useEffect。对于客户端用户,我们调用函数创建一个麦克风 input,并对 input 进行分析,然后在 setInterval 内生成一个音量分数,如果该分数超过特定值,就说明用户正在说话。如果用户取消静音,就会调用 clearInterval 函数,UI 随之更新。此时,“speaking”状态被应用。
useEffect(() => {
const startAudioCheck = async () => {
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true })
const audioContext = new AudioContext();
const mediaStreamAudioSourceNode = audioContext.createMediaStreamSource(mediaStream);
const analyserNode = audioContext.createAnalyser();
mediaStreamAudioSourceNode.connect(analyserNode);
const pcmData = new Float32Array(analyserNode.fftSize);
const checkAudio = () => {
analyserNode.getFloatTimeDomainData(pcmData);
let sumSquares = 0.0;
for (const amplitude of pcmData) { sumSquares += amplitude * amplitude; }
let vol = Math.sqrt(sumSquares / pcmData.length)
if (vol > 0.05 && !speaking) {
setSpeaking(true)
setTimeout(() => { setSpeaking(false) }, 2000)
}
};
if (user.audio === false) {
rtc.current.checkSpeakingInterval = setInterval(checkAudio, 100)
}
else {
clearInterval(rtc.current.checkSpeakingInterval)
}
}
if (user.client) {
startAudioCheck()
}
return () => {
// eslint-disable-next-line
clearInterval(rtc.current.checkSpeakingInterval)
}
// eslint-disable-next-line
}, [user.audio])
注意: Interval 存储在控制 RTC 客户端、localAudioTrack 和 VideoTrack 的 useRef 中。
const rtc = useRef({
// For the local client.
client: null,
// For the local audio and video tracks.
localAudioTrack: null,
localVideoTrack: null,
checkSpeakingInterval: null
});
用户通话音量控制
我们把远端音频轨道和本地音频轨道都保存在 audioTrack 键的用户状态中。
声网 RTC SDK 提供了远端/本地音频轨道的 .setVolume() 函数。我们可以在控件组件中使用这个函数来设置轨道音量。
return (
<div className='controls'>
{/* Button to Mute/Unmute Mic */}
{/* Button to Mute/Unmute Video */}
{<input type="number" placeholder="Volume" onChange={(e) => { let vol = parseInt(e.target.value); !isNaN(vol) && vol >= 0 && vol <= 1000 && (user.audioTrack.setVolume(parseInt(e.target.value))) }} />}
{/* Button to quit call if client */}
</div>
)
自定义音频控制
声网 RTC SDK 提供了下列音频控制 input:
rtc.current.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack({
encoderConfig: {
sampleRate: 48000,
stereo: true,
bitrate: 128,
},
})
大家也可以使用自己的音频源码,根据自己的需要调整音频源码:
const media = await navigator.mediaDevices.getUserMedia({ video: false, audio: true })
let audioTrack = media.getAudioTracks()[0]
rtc.current.localAudioTrack = AgoraRTC.createCustomAudioTrack({ mediaStreamTrack: audioTrack });
//You can manipulate the audioTrack here
总结
太棒了!!!现在你可以在 React 视频通话应用上使用各种音量控件啦~~
原文作者:Prakhar Soni
原文链接:Volume Controls using Agora RTC in a React JS App