使用声网为 React JS 视频通话应用添加音量控制功能

视频通话应用中集成音量功能(例如,控制用户的音量、提示说话者其麦克风处于静音状态以及使用音效)是一项费时费力的活儿,如果你也有这个苦恼,不妨看看本文,我们手把手教你如何添加这些功能。

把 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 键的用户状态中。

volume-controls-using-agora-sdk-in-a-react-js-application-1

声网 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 视频通话应用上使用各种音量控件啦~~

  • 你可以从 Github 仓库提取组件,然后直接在你的应用上执行这些组件。
  • 想了解更多其他功能,可以点击这里查看官方文档哦。
  • 点击 GitHub 查看本教程的代码库。


原文作者:Prakhar Soni
原文链接:Volume Controls using Agora RTC in a React JS App
推荐阅读
相关专栏
SDK 教程
167 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。