写点什么

融云 Web SDK 如何实现语音的收发 ?

发布于: 2021 年 03 月 16 日

根据融云的开发文档, 总结得出, 融云 WebSDK 需要的是一个 aac 格式的音频 url, 不关注 url 如何生成. 生成 url 的步骤由开发者实现


文档: https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#HQVCMsg


所以关注点放在以下几个问题:


1、Web 端能否实现语音录制


2、结合融云 SDK 实现语音的发送


3、结合融云 SDK 实现语音的接收和播放


Web 端能否实现语音录制


答案是可以. 不过只有部分浏览器支持, 录制的音频格式有很多限制, 且只有当前站点为 localhost 或 https 时才可使用


录制原理: getUserMediaMediaRecorder


使用 getUserMedia 获取音频流, 使用 MediaRecorder 录音获取音频数据


以下为录制 5s, 获取 File 对象的代码:


// 通过 getUserMedia 获取音频流
复制代码


navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
复制代码


  const mediaRecorder = new MediaRecorder(stream);
复制代码


  const chunks = [];
复制代码


  // 收集音频数据
复制代码


  mediaRecorder.ondataavailable = function (e) {
复制代码


    chunks.push(e.data);
复制代码


  };
复制代码


  // 监听音频录制停止
复制代码


  mediaRecorder.onstop = e => {
复制代码


    const blob = new Blob(chunks);
复制代码


    blob.lastModifiedDate = new Date();
复制代码


    const file = new File([blob], 'audio_file.aac', { type: "audio/aac" }); // 获取到 File 对象, 可将此对象上传至服务器, 获取音频 url
复制代码


  };
复制代码


  mediaRecorder.start(); // 开始录音. 此处自动开始, 读者可按产品逻辑点击某个按钮触发录音
复制代码


  setTimeout(function () { // 5s 倒计时自动停止录音. 读者可按产品逻辑设置停止时机
复制代码


    mediaRecorder.stop();
复制代码


  }, 5000)
复制代码


});
复制代码

获取到 file 对象后, 可将 file 上传至服务器, 获取音频的远端 url


经过测试, 发现录制的音频只能在集成了融云的 Android 端播放, iOS 端无法播放


经过搜集资料, 发现 MediaRecorder 录音的编码是有限制的, 默认是 webm 格式, 而融云支持播放的是 aac 格式


JS 官方文档也没有给出 MediaRecorder 具体支持的格式, 因为各个浏览器实现的编码都不同, 且就算编码格式支持, 也有可能因为计算资源不足而导致编码失败


官网提供以下代码检测支持状况:


var types = ["video/webm", 
复制代码


             "audio/webm", 
复制代码


             "video/webm\;codecs=vp8", 
复制代码


             "video/webm\;codecs=daala", 
复制代码


             "video/webm\;codecs=h264", 
复制代码


             "audio/webm\;codecs=opus", 
复制代码


             "video/mpeg"];
复制代码


复制代码


for (var i in types) { 
复制代码


  console.log( "Is " + types[i] + " supported? " + (MediaRecorder.isTypeSupported(types[i]) ? "Maybe!" : "Nope :(")); 
复制代码


  // 重点 API: MediaRecorder.isTypeSupported
复制代码


}
复制代码

经过一系列调研, 总结以下几点:


1、需要注意浏览器兼容问题 getUserMediaMediaRecorder


2、录制上传后的音频为 webm 格式. 融云 iOS 暂不支持播放. 读者可以尝试在录音时将录音数据编码由 webm 转化为 aac 格式. 也可以将数据传给服务端, 由服务端转换格式


3、要注意 getUserMedia 的安全限制. 要求访问站点必须为 localhosthttps


结合融云 SDK 实现语音的发送


根据文章前的描述. 获取到远端音频 url 后, 调用融云的发送消息方法就可以了


注意: 记得先 初始化连接 融云 SDK


var conversation = im.Conversation.get({
复制代码


  targetId: '接收方的 userId',
复制代码


  type: RongIMLib.CONVERSATION_TYPE.PRIVATE
复制代码


});
复制代码


conversation.send({
复制代码


  messageType: RongIMLib.MESSAGE_TYPE.HQ_VOICE, // 'RC:HQVCMsg'
复制代码


  content: {
复制代码


    remoteUrl: 'https://rongcloud-audio.cn.ronghub.com/audio_amr__RC-2020-03-17_42_1584413950049.aac?e=1599965952&token=CddrKW5AbOMQaDRwc3ReDNvo3-sL_SO1fSUBKV3H:CDngyWj7ZApNmAfoecng7L_3SaU=', // 音频 url, 建议格式: aac
复制代码


    duration: 6, // 音频时长
复制代码


    type: 'aac'
复制代码


  }
复制代码


}).then(function(message){
复制代码


  console.log('发送语音消息成功', message);
复制代码


});
复制代码

结合融云 SDK 实现语音的接收和播放


发送: 依照融云文档设置消息监听即可


var im = RongIMLib.init({ appkey: '' }); // 建议全局只初始化一次
复制代码


var conversationList = []; // 当前已存在的会话列表
复制代码


im.watch({
复制代码


  message: function(event){
复制代码


    var message = event.message;
复制代码


    console.log('有人给我发消息啦: ', message);
复制代码


  }
复制代码


});
复制代码

播放: 融云发送的音频默认格式为 aac 格式. Web 端使用 audio 标签直接播放即可


播放时遇到的坑:


Web 收到的消息不是 aac 格式, 而是 amr 格式:


测试时发现 Android 发送的语音消息是 RC:VcMsg, 而不是 RC:HQVCMsg


查看文档, 发现 RC:VcMsg 是融云旧语音消息, RC:HQVCMsg 是新语音消息. 但是融云移动端 IMKit 默认发送还是旧语音消息


根据文档提供的切换接口, 将 Android 发送语音改为 RC:HQVCMsg, 此问题成功解决了


切换文档: https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/android.html#voice


用户头像

还未添加个人签名 2021.01.26 加入

还未添加个人简介

评论

发布
暂无评论
融云 Web SDK 如何实现语音的收发 ?