<template> 
 | 
  <div class="container"> 
 | 
    <div class="header"> 
 | 
      <div> 
 | 
        房间号: 
 | 
        <input type="text" id="room" /> 
 | 
        <button @click="createRoom()">创建房间</button> 
 | 
      </div> 
 | 
      <div> 
 | 
        对方房间号 
 | 
        <input type="text" id="receive" /> 
 | 
        <button @click="Connect()">连接</button> 
 | 
      </div> 
 | 
    </div> 
 | 
    <div style="margin-top: 20px"> 
 | 
      <video 
 | 
        src="" 
 | 
        id="self" 
 | 
        autoplay 
 | 
        controls 
 | 
        muted 
 | 
        style="width: 500px; object-fit: cover; margin-right: 100px" 
 | 
      ></video> 
 | 
      <video 
 | 
        src="" 
 | 
        id="other" 
 | 
        autoplay 
 | 
        controls 
 | 
        muted 
 | 
        style="width: 500px; object-fit: cover" 
 | 
      ></video> 
 | 
    </div> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
let PeerConnection = 
 | 
  window.PeerConnection || 
 | 
  window.webkitPeerConnection00 || 
 | 
  window.webkitRTCPeerConnection || 
 | 
  window.mozRTCPeerConnection; 
 | 
let nativeRTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate; 
 | 
let nativeRTCSessionDescription = 
 | 
  window.mozRTCSessionDescription || window.RTCSessionDescription; 
 | 
//ice服务器地址 
 | 
const iceServer = { 
 | 
  iceServers: [ 
 | 
    { 
 | 
      url: "turn:42.192.40.58:3478?transport=udp", 
 | 
      username: "ddssingsong", 
 | 
      credential: "123456", 
 | 
    }, 
 | 
    { 
 | 
      url: "turn:42.192.40.58:3478?transport=tcp", 
 | 
      username: "ddssingsong", 
 | 
      credential: "123456", 
 | 
    }, 
 | 
  ], 
 | 
}; 
 | 
let socket = ""; 
 | 
let receiver = ""; 
 | 
let pc; 
 | 
  
 | 
export default { 
 | 
  data() { 
 | 
    return {}; 
 | 
  }, 
 | 
  
 | 
  created() {}, 
 | 
  
 | 
  methods: { 
 | 
    createRoom() { 
 | 
      let room = document.getElementById("room"); 
 | 
      if (!room.value) { 
 | 
        alert("请输入房间号!!!"); 
 | 
        return; 
 | 
      } 
 | 
      //建立websocket连接 
 | 
      socket = new WebSocket(`wss://127.0.0.1:3000/single?room=${room.value}`); 
 | 
      socket.onopen = async () => { 
 | 
        alert("连接成功"); 
 | 
        try { 
 | 
          //获取当前设备的视频流 
 | 
          let stream = await navigator.mediaDevices.getDisplayMedia({ 
 | 
            video: true, 
 | 
            audio: false, 
 | 
          }); 
 | 
          console.log(stream); 
 | 
          //初始化PC源 
 | 
          pc = this.initPC(stream); 
 | 
          console.log(pc); 
 | 
          //添加音视频流 
 | 
          pc.addStream(stream); 
 | 
          console.log(pc); 
 | 
          let video = document.getElementById("self"); 
 | 
          video.srcObject = stream; 
 | 
          console.log(video); 
 | 
        } catch (error) { 
 | 
          console.log(error); 
 | 
          alert("获取流失败"); 
 | 
        } 
 | 
      }; 
 | 
      socket.onmessage = async (message) => { 
 | 
        let data = JSON.parse(message.data); 
 | 
        switch (data.name) { 
 | 
          //接收到邀请 
 | 
          case "peer": 
 | 
            receiver = data.receiver; 
 | 
            this.acceptAudio(); 
 | 
            break; 
 | 
          /** 
 | 
           * 1.邀请人将对方的音视频流通过setRemoteDescription函数进行存储 
 | 
           * 2.存储完后邀请人创建answer来获取自己的音视频流,通过setLocalDescription函数存储自己的音视频流,并发送answer指令(携带自己的音视频)告诉对方要存储邀请人的音视频 
 | 
           */ 
 | 
          case "offer": 
 | 
            //当收到对方接收请求后,设置音频源,并发送answer给对方 
 | 
            pc.setRemoteDescription( 
 | 
              new nativeRTCSessionDescription(data.data.sdp) 
 | 
            ); 
 | 
            pc.createAnswer( 
 | 
              (session_desc) => { 
 | 
                pc.setLocalDescription(session_desc); 
 | 
                socket.send( 
 | 
                  JSON.stringify({ 
 | 
                    name: "answer", 
 | 
                    data: { 
 | 
                      sdp: session_desc, 
 | 
                    }, 
 | 
                    receiver: receiver, 
 | 
                  }) 
 | 
                ); 
 | 
              }, 
 | 
              (err) => { 
 | 
                console.log(err); 
 | 
              } 
 | 
            ); 
 | 
            break; 
 | 
          case "answer": 
 | 
            //设置邀请人发来的音频源 
 | 
            pc.setRemoteDescription( 
 | 
              new nativeRTCSessionDescription(data.data.sdp) 
 | 
            ); 
 | 
            break; 
 | 
          case "ice_candidate": 
 | 
            //添加ice源,这一步很重要,如果没有接收ice则查看是否流程有问题 
 | 
            var candidate = new nativeRTCIceCandidate(data.data); 
 | 
            pc.addIceCandidate(candidate); 
 | 
            break; 
 | 
        } 
 | 
      }; 
 | 
    }, 
 | 
    //初始化PC源 
 | 
    initPC() { 
 | 
      let pc = new PeerConnection(iceServer); 
 | 
      pc.onicecandidate = (evt) => { 
 | 
        if (evt.candidate) { 
 | 
          socket.send( 
 | 
            JSON.stringify({ 
 | 
              name: `ice_candidate`, 
 | 
              data: { 
 | 
                id: evt.candidate.sdpMid, 
 | 
                label: evt.candidate.sdpMLineIndex, 
 | 
                sdpMLineIndex: evt.candidate.sdpMLineIndex, 
 | 
                candidate: evt.candidate.candidate, 
 | 
              }, 
 | 
              receiver: receiver, 
 | 
            }) 
 | 
          ); 
 | 
        } 
 | 
      }; 
 | 
      pc.onaddstream = (evt) => { 
 | 
        let stream = evt.stream; 
 | 
        let video = document.getElementById("other"); 
 | 
        video.srcObject = stream; 
 | 
      }; 
 | 
      return pc; 
 | 
    }, 
 | 
    //和对方建立连接 
 | 
    Connect() { 
 | 
      receiver = document.getElementById("receive").value; 
 | 
      console.log(receiver); 
 | 
      if (!socket) { 
 | 
        alert("先创建自己的房间号!!"); 
 | 
        return; 
 | 
      } 
 | 
      if (!receiver) { 
 | 
        alert("请输入对方房间号"); 
 | 
        return; 
 | 
      } 
 | 
      socket.send(JSON.stringify({ name: "createRoom", receiver: receiver })); 
 | 
      console.log("成功"); 
 | 
    }, 
 | 
    //接收邀请 
 | 
    async acceptAudio() { 
 | 
      /** 
 | 
       * 1.点击同意后 
 | 
       * 2.获取自己的视频流 
 | 
       * 3.初始化PC源 
 | 
       * 4.PC添加音视频流 
 | 
       * 5.创建offer,获取自己的音视频流,并通过setLocalDescription函数存储自己的音视频流 
 | 
       * 6.并发送peer指令(携带自己的音视频)告诉邀请人要存储自己的音视频 
 | 
       */ 
 | 
      try { 
 | 
        pc.createOffer( 
 | 
          (session_desc) => { 
 | 
            pc.setLocalDescription(session_desc); 
 | 
            socket.send( 
 | 
              JSON.stringify({ 
 | 
                name: "offer", 
 | 
                data: { 
 | 
                  sdp: session_desc, 
 | 
                }, 
 | 
                receiver: receiver, 
 | 
              }) 
 | 
            ); 
 | 
          }, 
 | 
          (err) => { 
 | 
            console.log(err); 
 | 
          } 
 | 
        ); 
 | 
      } catch (error) { 
 | 
        alert("检测到当前设备不支持麦克风,请设置权限后在重试"); 
 | 
        this.socket.close(); 
 | 
      } 
 | 
    }, 
 | 
  }, 
 | 
}; 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped></style> 
 |