带你轻松实现web版的多人视频聊天室

864 阅读4分钟

web版的多人视频聊天室

上次向大家展示的web版视频通话怎么样,有没有人尝试做出来呢?是不是非常简单呢,那,今天我就带大伙进行开发多人视频的视频聊天室吧!相信大家都等不及了吧!嘻嘻🤭,那就直接进入项目吧!

一、项目准备

需求:web端的多人视频聊天

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

需要使用到的RTM - SDK功能

需要使用的RTC - SDK功能

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

下载或引入 anyRTC

  • script导入 使用 <script> 标签引入 SDK 时,产生名为 ArRTM 的全局变量,该变量含有该模块的所有成员。
<script src="https://ardw.anyrtc.io/sdk/web/ArRTM@latest.js"></script> //引入RTM
<script src="https://ardw.anyrtc.io/sdk/web/ArRTC@latest.js"></script> //引入RTC
  • npm 导入
npm install --save ar-rtm-sdk; 
import ArRTM from "ar-rtm-sdk"; //导入RTM项目

npm install --save ar-rtc-sdk;
import ArRTC from "ar-rtc-sdk"; //导入RTC项目

RTM相关

- 创建rtm实例

var rtmClient = ArRTM.createInstance(App ID );
rtmClient.login({uid: 用户id}); //用户id唯一 登录成功后才可以使用RTM
//rtmClient.logout(); //退出登录

- 被邀请用户(接受者)

//收到主叫邀请用户
rtmClient.on("RemoteInvitationReceived", function (remoteInvitation) {
     remoteInvitation.accept(); //接受邀请  
    //remoteInvitation.refuse();//拒绝邀请
   .......
   //返回给被叫:接受呼叫邀请成功。
   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) {});
}

- 主叫邀请(发起者)

//RTM 加入频道  channelId 频道名称
RTM.joinChannel(channelId);
/查询被邀请用户的状态   被邀请用户id calleeId 唯一
// 查询呼叫的用户是否在线
var userOnlineStatus = await Store.rtmClient.queryPeersOnlineStatus(Store.invitationUserIds);
var oArray = [];
// 遍历邀请(不在线的用户不发送邀请)
Store.invitationUserIds.map(function(userid, value) {
   //不在线
  if (!userOnlineStatus[userid]) {
	 oArray.push(userid);
  }
});
oArray.map(function(usser) {
	if (Store.invitationUserIds.indexOf(usser) != -1) {
			Store.invitationUserIds.splice(Store.invitationUserIds.indexOf(usser), 1)
	};
});
if (Store.invitationUserIds.length > 0) {
	// 显示会议页面
    ......
   Store.invitationUserIds.map(function(userid) {
		// 创建用户视图窗口
        ......
        // 创建呼叫邀请并发送
		var localInvitation = RTM.createLocalInvitationAndSend(userid, channelId);
  });
 }
 //采集本地音视频并发布
......

//返回给主叫:被叫已收到呼叫邀请。
localInvitation.on("LocalInvitationReceivedByPeer", function () {
   //对方收到邀请,说明对方已经上线,这个时候应该监听对方的在线状态,如果对方离线 主动取消邀请(防止对方刷新或掉线时无法通知服务端)
});
//返回给主叫:被叫已接受呼叫邀请。
localInvitation.on("LocalInvitationAccepted", async function (response) {});
//远端用户拒绝了你的呼叫邀请
localInvitation.on("LocalInvitationRefused", function (response) {});
//返回给主叫:呼叫邀请已被成功取消。
localInvitation.on("LocalInvitationCanceled", function () {});
//返回给主叫:呼叫邀请进程失败。
localInvitation.on("LocalInvitationFailure", function (reason) {});
.......
//发起者取消呼叫
//localInvitation.cancel();
......

RTC相关

- 创建rtc实例

//mode 编码格式  codec 使用场景
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 () {
    //获取频道内的人数
    var userNum = await RTM.rtmChannel.getMembers();
    //当频道内的人数仅剩一人时自动退出房间
    if (userNum.length >= 2) {
	  CustomUI.alertWhole("用户" + user.uid + "离开", "alert-danger");
	  // 移除用户窗口
    } else {
      //释放资源
      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);

三、参考

参考 anyRTC ARCall

github.com/anyRTC-UseC…

作者:用户3570988478894 链接:juejin.cn/post/686558… 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。