首页 > 其他分享 >网站在线客服系统实时语音视频聊天实战开发,利用peerjs vue.js实现webRTC网页音视频客服系统

网站在线客服系统实时语音视频聊天实战开发,利用peerjs vue.js实现webRTC网页音视频客服系统

时间:2023-02-12 23:12:38浏览次数:57  
标签:function vue 客服 peerjs call peer 音视频

webRTC机制和peerjs库的介绍在其他博客中已经有了很多介绍,这里我直接搬运过来

一、webrtc回顾

WebRTC(Web Real-Time Communication)即:网页即时通信。 简单点讲,它可以实现浏览器网页与网页之间的音视频实时通信(或传输其它任何数据),目前主流浏览器都支持该API,WebRTC现在已经纳入W3C标准。

1.1 媒体协商
通信的主要目的之一是彼此交换信息。打个比方:“张三”跟“李四”打了一通电话(语音通讯),整个过程中“张三”说的话被“李四”听到了,“李四”说的话被“张三”听到了,双方交换了语音信息。类似的,一个浏览器要与另一个浏览器发起实时音视频通信,需要交换哪些信息呢? 除了音视频信息外,至少还有2个关键信息要交换:媒体信息和网络信息。

如上图:通常某个浏览器所在的电脑,都会连接具体的多媒体设备(比如:麦克风、摄像头)。如果A电脑上的摄像头只支持VP8,H264格式,而另一台电脑上的摄像头只支持H264、MPEG-4格式,它俩要能正常播放彼此的视频,肯定会选择双方都能识别的H264格式。这就好比:2个不同国籍的人要相互交流,A会说英语、中文;而B只会说英语,毫无悬念,他俩肯定会用双方都能听懂的“英语”来沟通。

 

网络情况也是类似的,二个浏览器所在的电脑可能在不同的网络环境中,假如A机器具备公网+192内网网段,而B机器只有192+198内网网段,二台电脑要能相互连接,很容易想到,使用双方都能连通的公共192内网网段通信最为方便。
在webrtc中,有一个特定的协议用于描述媒体信息、网络信息和其它一些关键信息,称为SDP(Session Description Protocol-会话描述协议)。而上述介绍的交换媒体信息、网络信息的过程,也被称为媒体协商,即:交换SDP.

这是一张媒体协商过程的经典图例, Amy要跟Bob通信, 要先发一个Offer(即: 描述Amy自己会话的SDP), Bob收到后,做出Answer回应(即:描述Bob自己会话的SDP), 双方完成SDP交换后, 根据前面的分析,取出二份SDP的交集, 即完成了媒体协商.

1.2 主要处理过程

这是mozilla开发者官网上的一张图, 大致描述了webrtc的处理过程:

  • A通过STUN服务器,收集自己的网络信息
  • A创建Offer SDP,通过Signal Channel(信令服务器)给到B
  • B做出回应生成Answer SDP,通过Signal Channel给到A
  • B通过STUN收集自己的网络信息,通过Signal Channel给到A

注:如果A,B之间无法直接穿透(即:无法建立点对点的P2P直连),将通过TURN服务器中转。

二、下载引入peerjs

vue环境下引入第三方库,并且不是使用npm包的形式,在官网下载peer.js,放入src/tools/目录里

在聊天页面的vue中,引入这个函数库

import "../tools/peer.js"

发送语音邀请

在html中增加一个请求通话的按钮,点击的时候调用指定函数,效果如图:

 

 

 

                    <div class="iconExtendBtn" @click="callPhone()">
                        <div class="elIcon el-icon-phone-outline" style="font-size: 22px;"></div>
                        <div>语音</div>
                    </div>

实现这个点击函数,我们需要获取到当前设备的音频和视频流,需要访问访问用户的音频和视频设备(如摄像头和麦克风),这样我们就拿到了本地音视频流

另一篇文章有介绍最兼容的getUserMedia获取音视频流的函数方法

拿到音视频流以后再去初始化一下PeerJs服务,拿到peerjs的id,这个ID就是我们通话的身份ID,非常重要

            //语音请求
            callPhone(){
                var _this=this;
                let res=tools.getCompatibleUserMedia({video:true, audio: {
                    noiseSuppression: true,
                    echoCancellation: true,
                }},function(stream) {
                    _this.initPeerjs(function(peerid){
                        //初始化成功
                        _this.peerjs.peerjsId=peerid;
                        _this.peerjs.localStream=stream;
                    });
                },function(err) {
                    _this.$message({
                        type: 'error',
                        message: err
                    });
                });
                if(!res){
                    _this.$message({
                        type: 'error',
                        message: "Your browser does not support the getUserMedia API."
                    });
                }
            },
            //初始化peer
            initPeerjs(callback){
                let peer = new Peer();
                this.peerjs.peer=peer;
                var _this=this;
                peer.on('open', function(id) {
                    console.log('My peer ID is: ' + id);
                    callback(id);
                });
                peer.on('close', function() {
                    console.log('My peer close');
                });
                peer.on('disconnected', function() {
                    console.log('My peer disconnected');
                });
                peer.on('error', function() {
                    console.log('My peer error');
                });
            }

我们想对客服发起语音通话,那么就需要拿到客服的peerid,那怎么才能知道客服的peerid呢?

那么我们在初始化好自己的peerid以后,调用一个后端接口,让客服把他们的peerid发过来,这样我们才能知道客服的peerid

                        //请求客服发送他们的peerid过来
                        _this.$axios.post(_this.ApiHost+'/2/callKefu',{"action":"callpeer",kefu_id:_this.visitor.to_id,visitor_id:_this.visitor.visitor_id});
                        _this.$message({
                            type: 'success',
                            message: "请求通话指令已经发出!"
                        });

同样,后端客服在接收到访客请求通话的指令后,就初始化自己的peerjs ID,然后调用后端接口,把自己的peerjs ID传递过来(这里暂时先略过客服端的操作)

我们在WebSocket中接收到客服的peerjs ID以后进行远程调用操作

                     //客服接受通话
                    if(type=="accept"){
                        _this.peerjs.kefuPeerId=data;
                        //访客调用客服
                        _this.callPeer();
                    }
            //call peer
            callPeer(){
                var _this=this;
                //调用请求远程客服
                let call = _this.peerjs.peer.call(_this.peerjs.kefuPeerId, _this.peerjs.localStream);
                call.on('stream', function(remoteStream) {
                    console.log("call stream",remoteStream);
                });
                call.on('close', function() {
                    console.log("call close");
                });
                call.on('error', function(err) {
                    console.log("call error",err);
                });
                this.peerjs.call=call;
            }

这样就在call.on('stream')中拿到了客服的音视频流,现在只需要把这个音视频流展示到界面上就可以了

 

 界面上加上两个标签video和audio

        <div class="coverMask" v-show="peerjs.remoteVideoStream">
            <video id="remoteVideo" controls autoplay></video>
        </div>
        <div class="coverMask" v-show="peerjs.remoteAudioStream">
            <audio id="remoteAudio" controls autoplay></audio>
        </div>

把获取到的视频流,音频流展示出来

                call.on('stream', function(remoteStream) {
                    console.log("call stream",remoteStream);
                    var videoTracks = remoteStream.getVideoTracks();
                    var audioTracks = remoteStream.getAudioTracks();
                    //视频流
                    if (videoTracks.length > 0) {
                        var remoteVideo = document.getElementById("remoteVideo");
                        remoteVideo.srcObject = remoteStream;
                        remoteVideo.play();
                        _this.peerjs.remoteVideoStream=remoteStream;
              return; } //音频流 if (audioTracks.length > 0) { var remoteAudio = document.getElementById("remoteAudio"); remoteAudio.srcObject = remoteStream; remoteAudio.play(); _this.peerjs.remoteAudioStream=remoteStream; } });

 

 

标签:function,vue,客服,peerjs,call,peer,音视频
From: https://www.cnblogs.com/taoshihan/p/17111840.html

相关文章

  • 【前端工具】nodejs+npm+vue 安装(windows)
    预备先看看这几个是干嘛的,相互的关系是啥。nodejs是语言,类比到php。npm是个包管理,类比到composer。vue是个框架,类比到laravel。webpack是个打包工具。先下载nodejs......
  • 【Vue day01】前端发展介绍 Vue的快速使用 插值语法 指令系统之文本指令、事件指令、
    目录前端发展介绍Vue框架入门M-V-VM思想组件化开发单页面应用Vue的快速使用前期准备快速使用对象与标签绑定查看Vue对象插值语法三目运算符指令系统之文本指令v-text和v-......
  • vuexalong解决刷新缓存丢失
    脚手架安装vuexalongnpminstallvuex-along--save在Vuex的配置文件中使用↑↑↑↑到这里你已经可以使用了 ↑↑↑↑↑  这样Vue-along会将state中的所有数......
  • 基于Java+Springmvc vue+element员工信息管理系统详细设计
    基于Java+Springmvc+vue+element员工信息管理系统详细设计前言介绍:系统管理也都将通过计算机进行整体智能化操作,对于企业员工考勤管理系统所牵扯的管理及数据保存都是非常......
  • vue3自定义指令
    前言很多时候我们写的方法是通用的,这个时候根据使用场景可以选择放在js或者ts文件并让其他文件引入使用,但如果是对现有组件添加新功能的话,还是建议用自定义指令更方便......
  • vue 主路由和子路由
    路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的about按钮,页面中就要显示about的内容。Home按钮=>home内容,about按钮=......
  • 利用python自动将下载好的音视频合成
    网上看到一个油猴脚本,可以自动下载任何视频,下载后自动生成音频和视频,需要用到ffmpeg对音视频进行合成,于是花了几个小时写了一个python脚本,实现自动扫描并合成视频功能使用......
  • vue学习
    推荐大家安装的VScode中的Vue插件Vue3Snippetshttps://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippetsVeturht......
  • vue2 data 一定要是函数吗?
    答:不一定,可以是对象,vue文档中表述有误导性而已,他自己的例子里也有对象的形式functioninitData(vm){letdata=vm.$options.datadata=vm._data=typeofdata......
  • Vue_Webpack
    前端工程化模块化(js复用)组件化(UI复用,layui)规范化(各种规范)自动化(自动构建、自动部署、自动化测试)前端工程化指的是:在企业级的前端项目开发中,把前端开发所......