WebRTC实现视频通话

A,B,C三人群聊,首先各自都要创建一个不包含本身的peers例如A:peers=[{name:“b”,peer:null,id:***},{name:“c”,peer:null,id:***}],B:peers=[{name:“a”,peer:null,id:***},{name:“c”,peer:null,id:***}],当建立连接时就是A的b对象和B的a对象之间发送offer,ice并建立连接,每个连接都是在一个单独的对象进行操作的

setLocalDescription()会触发 onicecandidate 事件
setRemoteDescription() 会触发 addStream 事件

根据群聊人数向peers添加房间内会存在的所有用户

 that.peers.push({id:v.id,perr:null,name:v.name,img:v.img})

给每个peer创建 new RTCPeerConnection(),根据已进入房间人数给每个人发送一个单独的offer

 ws.onmessage = (data) => {
          const message = JSON.parse(data.data)
          if (message.type == "searchRooom") {
            //给已进入房间所有人发送一个单独的offer
            that.room = message.room.users
            //判断peers的用户是否已进入房间
            that.peers.forEach((v)=>{
              for (let j of that.room ){
                if(j.id==v.id){
                  const iceServer = {
                    "iceServers": [
                      {
                        "urls": "stun:stun.l.google.com:19302"
                      }
                    ],
                  };
                  v.peer = new RTCPeerConnection(iceServer);
                  v.peer.onicecandidate = (evt) => {
                    //发送ice
                    ws.send(JSON.stringify({
                      type: 1,
                      candidate: evt.candidate,
                      chatType: "video",
                      roomID: that.isAnswerVideo.roomID,
                    }))
                  }
                  v.peer.onaddstream = (evt) => {
                    console.log("offer添加视屏")
                      document.getElementById("localVideo").srcObject = evt.stream
                  }
                  navigator.mediaDevices.getUserMedia({"audio": true, "video": true}).then(stram => {
                    v.peer.addStream(stram)
                    that.localStream = stram
                    localVideo.srcObject = stram
                    //创建并发送offer
                    v.peer.createOffer({
                      offerToReceiveAudio: 1,
                      offerToReceiveVideo: 1
                    }).then(offer => {
                      v.peer.setLocalDescription(offer, () => {
                        ws.send(JSON.stringify({
                          type: 1,
                          sdp: v.peer.localDescription,
                          chatType: "video",
                          id: that.userData.id,
                          roomID: that.isAnswerVideo.roomID,
                        }))
                      })
                    })
                  })
                }else
                {
                // peers的用户未进入房间创建peer,等待后进入房间的人给你发送offer
                  const iceServer = {
                    "iceServers": [
                      {
                        "urls": "stun:stun.l.google.com:19302"
                      }
                    ],
                  };
                  v.peer = new RTCPeerConnection(iceServer);
                  v.peer.onicecandidate = (evt) => {
                    ws.send(JSON.stringify({
                      type: 1,
                      candidate: evt.candidate,
                      chatType: "video",
                      roomID: that.isAnswerVideo.roomID,
                      name: that.userData.name,
                      id: that.userData.id,
                    }))
                  }
                  v.peer.onaddstream = (evt) =>{
                  //  你的逻辑
                  }
                  navigator.mediaDevices.getUserMedia({"audio": true, "video": true}).then(stram => {
                    v.peer.addStream(stram)
                  })
                }
              }
            })
          }

收到 ice

 if (message.candidate && message.candidate !== null) {
 //遍历peers给对应的peer添加ice
            that.peers.forEach(v=>{
              if(v.id==message.id){
                v.peer.addIceCandidate(new RTCIceCandidate(message.candidate))
              }
            })
          }

收到 offer

//收到offer遍历peers给对应的peer发送answer
  if (message.webtype == "video-offer") {
              // 创建
              this.videoSession(message)
            }
               videoSession(message) {
        const that = this
        const ws = that.$store.getters.wsChat
        that.peers.forEach(v=>{
          if(v.id==message.id){
            v.peer.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
              v.peer.createAnswer().then((desc) => {
                v.peer.setLocalDescription(desc, () => {
                  ws.send(JSON.stringify({
                    name: that.userData.name,
                    type: 1,
                    sdp: v.peer.localDescription,
                    chatType: "video",
                    webtype: "video-answer",
                    id: that.userData.id,
                    offerID: message.id,
                    offerName: message.name,
                    roomID: message.roomID
                  }))
                });
              })
            })
          }
        })
      },

收到 answer

//收到answer遍历peers给对应的peer添加远端描述
 if (message.webtype = "video-answer") {
              that.peers.forEach(v=>{
                if(v.id==message.id){
                  v.peer.setRemoteDescription(new RTCSessionDescription(message.sdp))
                }
              })
            }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值