当前位置:首页 » 《随便一记》 » 正文

vue项目基于WebRTC实现一对一音视频通话

7 人参与  2024年12月25日 16:01  分类 : 《随便一记》  评论

点击全文阅读


效果

前端代码

<template>  <div class="flex items-center flex-col text-center p-12 h-screen">    <div class="relative h-full mb-4 fBox">      <video id="localVideo"></video>      <video id="remoteVideo"></video>      <div v-if="caller && calling">        <p class="mb-4 text-white">等待对方接听...</p>        <img style="width: 60px;" @click="hangUp" src="@/assets/guaDuang.png" alt="">      </div>      <div v-if="called && calling">        <p>收到视频邀请...</p>        <div class="flex">          <img style="width: 60px" @click="hangUp" src="@/assets/guaDuang.png" alt="">          <img style="width: 60px" @click="acceptCall" src="@/assets/jieTing.png" alt="">        </div>      </div>    </div>    <div>      <button @click="callRemote" style="margin-right: 10px">发起视频</button>      <button @click="hangUp" style="margin-left: 10px">挂断视频</button>    </div>  </div></template>
<script>import { io, Socket } from "socket.io-client";let roomId = '001';export default {  name: 'HelloWorld',  props: {    msg: String  },  data(){    return{      wsSocket:null,//实例      called:false,// 是否是接收方      caller:false,// 是否是发起方      calling:false,// 呼叫中      communicating:false,// 视频通话中      localVideo:null,// video标签实例,播放本人的视频      remoteVideo:null,// video标签实例,播放对方的视频      peer:null,      localStream:null,    }  },  methods:{    // 发起方发起视频请求    async callRemote(){      let that = this;      console.log('发起视频');      that.caller = true;      that.calling = true;      // await getLocalStream()      // 向信令服务器发送发起请求的事件      await that.getLocalStream();      that.wsSocket.emit('callRemote', roomId)    },    // 接收方同意视频请求    acceptCall(){      console.log('同意视频邀请');      this.wsSocket.emit('acceptCall', roomId)    },    // 挂断视频    hangUp(){      this.wsSocket.emit('hangUp', roomId)    },    reset(){      this.called = false;      this.caller = false;      this.calling = false;      this.communicating = false;      this.peer = null;      this.localVideo.srcObject = null;      this.remoteVideo.srcObject = null;      this.localStream = undefined;      console.log('挂断结束视频-------')    },    // 获取本地音视频流    async getLocalStream(){      let that = this;      let obj = { audio: true, video: true };      const stream = await navigator.mediaDevices.getUserMedia(obj); // 获取音视频流      that.localVideo.srcObject = stream;      that.localVideo.play();      that.localStream = stream;      return stream;    }  },  mounted() {    let that = this;    that.$nextTick(()=>{      that.localVideo = document.getElementById('localVideo');      that.remoteVideo = document.getElementById('remoteVideo');    })    let sock = io('localhost:3000'); // 对应服务的端口    // 连接成功    sock.on('connectionSuccess', (sock) => {      console.log('连接成功:');    });    sock.emit('joinRoom', roomId) // 前端发送加入房间事件    sock.on('callRemote', (sock) => {      // 如果是发送方自己收到这个事件就不用管      if (!that.caller){ // 不是发送方(用户A)        that.called = true; // 接听方        that.calling = true; // 视频通话中      }    });    sock.on('acceptCall',async ()=>{      if (that.caller){        // 用户A收到用户B同意视频的请求        that.peer = new RTCPeerConnection();        // 添加本地音视频流        that.peer.addStream && that.peer.addStream(that.localStream);        // 通过监听onicecandidate事件获取candidate信息        that.peer.onicecandidate = (event) => {          if (event.candidate) {            console.log('用户A获取candidate信息', event.candidate);            // 通过信令服务器发送candidate信息给用户B            sock.emit('sendCandidate', {roomId, candidate: event.candidate})          }        }        // 接下来用户A和用户B就可以进行P2P通信流        // 监听onaddstream来获取对方的音视频流        that.peer.onaddstream = (event) => {          console.log('用户A收到用户B的stream',event.stream);          that.calling = false;          that.communicating = true;          that.remoteVideo.srcObject = event.stream;          that.remoteVideo.play();        }        // 生成offer        let offer = await that.peer.createOffer({          offerToReceiveAudio: 1,          offerToReceiveVideo: 1        })        console.log('offer', offer);        // 设置本地描述的offer        await that.peer.setLocalDescription(offer);        // 通过信令服务器将offer发送给用户B        sock.emit('sendOffer', { offer, roomId })      }    })    // 收到offer    sock.on('sendOffer',async (offer) => {      if (that.called){ // 接收方 - 用户B        console.log('收到offer',offer);        // 创建自己的RTCPeerConnection        that.peer = new RTCPeerConnection();        // 添加本地音视频流        const stream = await that.getLocalStream();        that.peer.addStream && that.peer.addStream(stream);        // 通过监听onicecandidate事件获取candidate信息        that.peer.onicecandidate = (event) => {          if (event.candidate) {            console.log('用户B获取candidate信息', event.candidate);            // 通过信令服务器发送candidate信息给用户A            sock.emit('sendCandidate', {roomId, candidate: event.candidate})          }        }        // 接下来用户A和用户B就可以进行P2P通信流        // 监听onaddstream来获取对方的音视频流        that.peer.onaddstream = (event) => {          console.log('用户B收到用户A的stream',event.stream);          that.calling = false;          that.communicating = true;          that.remoteVideo.srcObject = event.stream;          that.remoteVideo.play();        }        // 设置远端描述信息        await that.peer.setRemoteDescription(offer);        let answer = await that.peer.createAnswer();        console.log('用户B生成answer',answer);        await that.peer.setLocalDescription(answer);        // 发送answer给信令服务器        sock.emit('sendAnswer', { answer, roomId })      }    })    // 用户A收到answer    sock.on('sendAnswer',async (answer) => {      if (that.caller){ // 接收方 - 用户A   判断是否是发送方        // console.log('用户A收到answer',answer);        await that.peer.setRemoteDescription(answer);      }    })    // 收到candidate信息    sock.on('sendCandidate',async (candidate) => {      console.log('收到candidate信息',candidate);      // await that.peer.addIceCandidate(candidate) // 用户A和用户B分别收到candidate后,都添加到自己的peer对象上      // await that.peer.addCandidate(candidate)      await that.peer.addIceCandidate(candidate)    })    // 挂断    sock.on('hangUp',()=>{      that.reset()    })    that.wsSocket = sock;  }}</script>

服务端代码

const socket = require('socket.io');const http = require('http');const server = http.createServer()const io = socket(server, {    cors: {        origin: '*' // 配置跨域    }});io.on('connection', sock => {    console.log('连接成功...')    // 向客户端发送连接成功的消息    sock.emit('connectionSuccess');    sock.on('joinRoom',(roomId)=>{        sock.join(roomId);        console.log('joinRoom-房间ID:'+roomId);    })    // 广播有人加入到房间    sock.on('callRemote',(roomId)=>{        io.to(roomId).emit('callRemote')    })    // 广播同意接听视频    sock.on('acceptCall',(roomId)=>{        io.to(roomId).emit('acceptCall')    })    // 接收offer    sock.on('sendOffer',({offer,roomId})=>{        io.to(roomId).emit('sendOffer',offer)    })    // 接收answer    sock.on('sendAnswer',({answer,roomId})=>{        io.to(roomId).emit('sendAnswer',answer)    })    // 收到candidate    sock.on('sendCandidate',({candidate,roomId})=>{        io.to(roomId).emit('sendCandidate',candidate)    })    // 挂断结束视频    sock.on('hangUp',(roomId)=>{        io.to(roomId).emit('hangUp')    })})server.listen(3000, () => {    console.log('服务器启动成功');});

完整代码gitee地址: https://gitee.com/wade-nian/wdn-webrtc.git

参考文章:基于WebRTC实现音视频通话_npm create vite@latest webrtc-client -- --template-CSDN博客y

要是在拨打电话过程中,无法打开摄像头或者麦克风,浏览器也没有弹出获取摄像头及麦克风的权限运行,这是需要进行浏览器安全源的设置,步骤如下:

1、在 chrome 中 输入 chrome://flags/#unsafely-treat-insecure-origin-as-secure

2、找到Insecure origins treated as secure

3、添加你服务器的地址 例如:http://192.168.1.10:8080

4、选择Enabled属性

5、点击右下角的Relaunch即可


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/206757.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1