• 0

  • 0

如何简洁快速的实现简易web版的视频通话?

机器猫

机器学习

2个月前

一、背景

众所周知,浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转。WebRTC应运而生。WebRTC是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的JavaScript接口。说的简单明了一点就是让浏览器提供JS的即时通信接口。但是,使用WebRTC实现一个简易web版的视频通话很繁琐,无法简洁快速的进行开发,那么,如何简洁快速的实现简易web版的视频通话?本文将带大家一起来学习如何简洁快速的实现简易web版的视频通话。

为了简洁快速的实现我们的需求,我们就需要基于WebRTC基础上进行优化、集中的——anyRTC。大家肯定很好奇,anyRTC是什么?anyRTC 为开发者提供实时音视频 API,只需集成 anyRTC SDK,即可快速在应用内构建多种实时互动场景。开发者集成 anyRTC SDK 后,即可以调用不同 API,实现不同场景的实时互动。

 

 

二、项目准备

需求:web版的视频通话

用到的技术anyRTC的RTC实时音视频apianyRTC的RTM实时消息web api

注册anyRTC: 获取App ID

需要使用到的RTM - SDK功能

需要使用的RTC - SDK功能

三、项目开发以及相关js代码

下载或引入 anyRTC

  • script导入

使用 <script> 标签引入 SDK 时,产生名为 ArRTM 的全局变量,该变量含有该模块的所有成员。

<script src="https://ardw.anyrtc.io/sdk/web/ArRTM@latest.js"></script>
复制代码
  • npm 导入
npm install --save ar-rtm-sdk; 
import ArRTM from "ar-rtm-sdk";  //导入项目
复制代码

RTM相关

  • 创建rtm实例
var rtmClient = ArRTM.createInstance(App ID );
rtmClient.login({uid: 用户id}); //用户id唯一 登录成功后才可以使用RTM
//rtmClient.logout(); //退出登录
复制代码
  • 被邀请用户(接受者)
//收到主叫邀请用户
rtmClient.on("RemoteInvitationReceived", function (remoteInvitation) {
   //返回给被叫:接受呼叫邀请成功。
   remoteInvitation.on("RemoteInvitationAccepted", async function (response) {
      //获取传过来的频道房间
      var invitationResponse = JSON.parse(response);                
     //加入实时通讯频道
     await rtcClient.join(App ID, invitationContent.ChanId, null, null)     //采集并发布媒体流

   }
   //返回给被叫:拒绝呼叫邀请成功。
   remoteInvitation.on("RemoteInvitationRefused", function () {});
   //返回给被叫:主叫已取消呼叫邀请。
   remoteInvitation.on("RemoteInvitationCanceled", function (content) {});
   //返回给被叫:呼叫邀请进程失败。
   remoteInvitation.on("RemoteInvitationFailure", function (reason) {});
     
   //接受邀请
   remoteInvitation.accept();   //拒绝邀请
    //remoteInvitation.refuse();
}
复制代码

 

 

  • 主叫邀请(发起者)
..........
//查询被邀请用户的状态   被邀请用户id calleeId 唯一
var userOnlineResults = await rtmClient.queryPeersOnlineStatus([calleeId]);
if (!userOnlineResults[calleeId] || !userOnlineResults[calleeId]) {
    //不允许呼叫,因为对方不在线
    return;
}

//创建呼叫邀请
var localInvitation = rtmClient.createLocalInvitation(calleeId);

//这里将呼叫邀请的内容 设置为视频通讯时使用的频道id - 进入同一个频道
localInvitation.content = JSON.stringify({
  ChanId: "4562" , //符合命名规则即可
}); 

//发送呼叫邀请
localInvitation.send();

//返回给主叫:被叫已收到呼叫邀请。
localInvitation.on("LocalInvitationReceivedByPeer", function () {
   //对方收到邀请,说明对方已经上线,这个时候应该监听对方的在线状态,如果对方离线 主动取消邀请(防止对方刷新或掉线时无法通知服务端)
   rtmClient.subscribePeersOnlineStatus([localInvitation.calleeId]);
   rtmClient.on("PeersOnlineStatusChanged", (userOnlineStatus) => {
      if (userOnlineStatus[localInvitation.calleeId] === "OFFLINE" && Store.iscalling) {
    localInvitation.cancel();
      }
   });
});
//返回给主叫:被叫已接受呼叫邀请。
localInvitation.on("LocalInvitationAccepted", async function (response) {
     //获取传过来的频道房间
     var invitationResponse = JSON.parse(response);                //加入实时通讯频道
   await rtcClient.join(App ID, invitationContent.ChanId, null, null)
   //采集并发布媒体流});
//远端用户拒绝了你的呼叫邀请
localInvitation.on("LocalInvitationRefused", function (response) {});
//返回给主叫:呼叫邀请已被成功取消。
localInvitation.on("LocalInvitationCanceled", function () {});
//返回给主叫:呼叫邀请进程失败。
localInvitation.on("LocalInvitationFailure", function (reason) {});
.......
//发起者取消呼叫
//localInvitation.cancel();
.......
复制代码

 

 

RTC相关

  • 创建rtc实例
var rtcClient = ArRTC.createClient({
                      mode: "vp8", //编码格式
              codec: rtc //使用场景
                });
复制代码
  • 采集视频、音频 并进行预览、发布
......
//采集视频、音频设备
var [cameras, microhones] = await Promise.all([
            ArRTC.getCameras(),
            ArRTC.getMicrophones(),
        ]);
if (cameras.length === 0 && microhones.length === 0) {
    alert("上麦失败!确实麦克风和摄像头");
    return
}
if (cameras.length > 0 && microhones.length > 0) { 
    //创建音频、视频轨道
    [audioTrack, videoTrack] = await ArRTC.createMicrophoneAndCameraTracks(
                null, {
                    encoderConfig: {
                        bitrateMax: 1130,
                        // bitrateMin: ,
                        frameRate: 15,
                        height: 180,
                        width: 320,
                    }
                }
            );
} else {
    
    if (!videoTrack && !audioTrack) {
        alert("没有设备无法发布媒体流");
        return
    }
}
//预览本地图像      documentId 存放容器的id(html中的属性id)
videoTrack && videoTrack.play(documentId);
//把用户设置为主播角色
rtcClient.setClientRole("host");
//发布
rtcClient.publish([videoTrack, audioTrack])
复制代码
  • 监听相关回调
//通知远端用户发布了新的音频或者视频
rtcClient.on("user-published", async function (user, mediaType) {
   //订阅发布的音频或者视频
   await rtcClient.subscribe(user, mediaType);  
});
//通知远端用户取消发布了音频或视频
rtcClient.on("user-unpublished", async function (user, mediaType) {});
//远端用户加入频道
rtcClient.on("user-joined", function (user) {});
//远端用户离线
rtcClient.on("user-left", function () {
   //释放资源               
   videoTrack && (videoTrack.close(), videoTrack = null);
   audioTrack && (audioTrack.close(), audioTrack = null);
   rtcClient.leave(); //离开
});
//SDK 与服务器的连接状态发生改变回调
rtcClient.on("connection-state-change", async function (ConnectionState) {});
复制代码

视频开关、音频开关

//视频开关
  videoTrack.isMuted = !videoTrack.isMuted;
  videoTrack.setEnabled(!videoTrack.isMuted);
//音频开关
  audioTrack.isMuted = !audioTrack.isMuted;
  audioTrack.setEnabled(!audioTrack.isMuted);
复制代码

四、参考

相关demo

https://github.com/anyRTC-UseCase/ARCall

免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

机器学习

0

相关文章推荐

未登录头像

暂无评论