webRCT实时语音视频通话 结合 vue使用

这篇具有很好参考价值的文章主要介绍了webRCT实时语音视频通话 结合 vue使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:最近项目遇到了一个推送视频对话的需求,本身项目就用到了websocket推送,所以直接使用webRCT就行

使用websocket

封装了一个socket.js

export default class MSocket {
  constructor(config) {
    if (!config.url) {
      throw new Error('websocket url is invalid');
    }
    this.reconnectTimer = null;
    this.heartbeatTimer = null;
    this.isAlive = false; // 是否已经链接
    this.config = {
      url: '', // 链接路径
      // retry: Infinity, // 重连次数
      retry: 10, // 重连次数
      reconnectWait: 5 * 1000, // 重连间隔时间
      heartBeatWait: 10 * 1000, // 心跳包发送间隔时间
      heartMsg: 'test', // 心跳包发送数据
      isHeartBeat: true // 是否开启心跳包
    };
    Object.keys(config).forEach(key => {
      this.config[key] = config[key]
    });
    this.init();
  }

  init() {
    this.socket = new WebSocket(this.config.url);

    this.socket.onerror = (e) => {
      this.reconnect();
      this.isAlive = false;
      clearInterval(this.config.heartbeatTimer);
      typeof this.config.onerror === 'function' && this.config.onerror(e);
    };

    this.socket.onmessage = ({ data }) => {
      const res = data.indexOf('{') > -1 ? JSON.parse(data) : data;
      typeof this.config.onmessage === 'function' && this.config.onmessage(res);
    }

    this.socket.onclose = (e) => {
      this.isAlive = false;
      clearInterval(this.config.heartbeatTimer);
      console.info('websocket was closed');
      typeof this.config.onclose === 'function' && this.config.onclose(e);
    }

    this.socket.onopen = (e) => {
      console.info('websocket was opened');
      this.isAlive = true;
      if (this.config.isHeartBeat) {
        this.startHeart();
      }
      typeof this.config.onopen === 'function' && this.config.onopen(e);
    }
  }

  // 发送数据
  send(data) {
    if (!this.isAlive) return
    const text = typeof data === 'string' ? data : JSON.stringify(data)
    this.socket.send(text)
  }

  // 关闭链接
  close() {
    this.isAlive = false;
    this.socket && this.socket.close();
  }

  // 自动重连
  reconnect() {
    this.reconnectTimer = setTimeout(() => {
      if (this.config.retry > 0) {
        this.config.retry--
        this.init()
      }
    }, this.config.reconnectWait)
  }

  // 自动心跳包
  startHeart() {
    this.heartbeatTimer = setInterval(() => {
      this.send(this.config.heartMsg)
    }, this.config.heartBeatWait)
  }
}

template

  <!-- <video id="localVideo" autoplay></video> --> //本地视频
        <video id="remoteVideo" autoplay></video> // 远程视频
        <el-button type="success" class="button-box" @click="cutStation">切换工位</el-button>

引入和data数据

import MSocket from '@/utils/socket.js';

data() {
    return {
      mediaConstraints: {
        video: false,
        audio: true, // true,//由于没有麦克风,所有如果请求音频,会报错,不过不会影响视频流播放
      },
      TYPE_COMMAND_READY: "ready",
      TYPE_COMMAND_OFFER: "offer",
      TYPE_COMMAND_ANSWER: "answer",
      TYPE_COMMAND_CANDIDATE: "candidate",
      TYPE_COMMAND_CALLFROMCENTER: "call_from_center",
      localMediaStream: "",
      rtcPeerConnection: "",
      offerOptions: {
        iceRestart: true,
        offerToReceiveAudio: true, //true,由于没有麦克风,所有如果请求音频,会报错,不过不会影响视频流播放
        offerToReceiveVideo: true,
      },
      userId: '',
      stationVlaue: 'up'
    };
  },

使用

 connection() {
      //初始化weosocket
      const _this = this
      const id= this.sessionData.id|| ""
      const userId = _this.userId
      _this.socketed = new MSocket({
        url: `ws://XXXXXXXX/ws`,  // ws 链接地址
        onerror: (e) => {
          console.log(e, '错误信息');
        },
        onmessage: (event) => {
          let message = event || {};
          if (message.type == "peers") {
            let data = message.data;
            for (var item of data) {
              if (item.id == id) {
                _this.video(id); //是id
              }
            }
          }

          if (message.type == "offer") {
            let sdpMessage = JSON.stringify(message.data.description);
            sdpMessage.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
            let sdp = JSON.parse(sdpMessage);
            //初始化一个webrtc端点 .
            _this.rtcPeerConnection = new RTCPeerConnection({
              bundlePolicy: "max-compat",
            });
            //添加事件监听函数
            _this.rtcPeerConnection.onicecandidate = _this.onIceCandidate;
            _this.rtcPeerConnection.ontrack = _this.onTrack;
            try {
              _this.rtcPeerConnection
                .setRemoteDescription(new RTCSessionDescription(sdp))
                .then(console.log("setRemoteDescription 完毕"));
              _this.rtcPeerConnection
                .createAnswer(_this.offerOptions)
                .then(_this.setLocalAndAnswer)
                .catch(() => {
                  console.log("setLocalAndAnswer error");
                });
            } catch (error) {
              console.log(error);
            }
          }

          if (message.type == "answer") {
            let sdpMessage = JSON.stringify(message.data.description);
            sdpMessage.replace(/\n/g, "\\n").replace(/\r/g, "\\r");
            let sdp = JSON.parse(sdpMessage);
            console.log(sdpMessage);
            _this.rtcPeerConnection
              .setRemoteDescription(new RTCSessionDescription(sdp))
              .then(() => {
                console.log("setRemoteDescription完毕");
              });
            // rtcPeerConnection.createAnswer(offerOptions).then(setLocalAndAnswer);
          }

          if (message.type == "candidate") {
            let candidateMessage = JSON.stringify(message.data);
            let candidate = JSON.parse(candidateMessage).candidate;
            let rtcIceCandidate = new RTCIceCandidate({
              sdpMid: candidate.sdpMid,
              sdpMLineIndex: candidate.sdpMLineIndex,
              candidate: candidate.candidate,
            });
            _this.rtcPeerConnection
              .addIceCandidate(rtcIceCandidate)
              .then(() => {
                console.log("addIceCandidate完毕");
              })
              .catch((error) => {
                console.log(error);
              });
          }

          if (message.type == "bye") {
            let remoteVideo = document.getElementById("remoteVideo");
            remoteVideo.srcObject = null;
          }
        },
        onopen: () => {
          console.log("连接服务器成功");
          _this.socketed.send(
            JSON.stringify({
              type: "new",
              data: {
                name: "Flutter Web",
                //操作员工号
                id: userId,
                user_agent:
                  "flutter-webrtc/web-plugin 0.0.1  ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) flutter-webrtc-demo/1.0.0 Chrome/94.0.4606.71 Electron/15.1.2 Safari/537.36 )",
              },
            })
          );
          _this.openLocalMedia();
        }
      });
    },
    openLocalMedia() {
      console.log(navigator, 'navigator')
      window.navigator.mediaDevices
        .getUserMedia(this.mediaConstraints)
        .then(res => {
          this.openLocalMediaSuccess(res)
        })
        .catch(err => {
          this.openLocalMediaError(err)
        });
    },
    openLocalMediaError(error) {
      console.error("getUserMedia error: " + error);
    },
    openLocalMediaSuccess(mediaStream) {
      // const video = document.getElementById("localVideo");
      // video.srcObject = mediaStream;   // 我这边不需要本地视频  需要可以放开注释
      this.localMediaStream = mediaStream;
      console.log(mediaStream);
      this.socketed.send(
        JSON.stringify({ command: this.TYPE_COMMAND_READY, userId: this.userId })
      );
    },
    //远程视频
    video(id) {
      //初始化一个webrtc端点 .
      const _this = this
      _this.rtcPeerConnection = new RTCPeerConnection({ bundlePolicy: "max-compat" });
      //添加事件监听函数
      _this.rtcPeerConnection.onicecandidate = _this.onIceCandidate;
      _this.rtcPeerConnection.ontrack = _this.onTrack;
      try {
        if (!_this.localMediaStream) {
          setTimeout(() => {
            for (const track of _this.localMediaStream.getTracks()) {
              _this.rtcPeerConnection.addTrack(track, _this.localMediaStream);
            }
            _this.rtcPeerConnection
              .createOffer(_this.offerOptions)
              .then(_this.setLocalAndOffer)
              .catch(() => {
                console.log("异常211");
              });
          }, 1000);
        } else {
          for (const track of _this.localMediaStream.getTracks()) {
            _this.rtcPeerConnection.addTrack(track, _this.localMediaStream);
          }
          _this.rtcPeerConnection
            .createOffer(_this.offerOptions)
            .then(_this.setLocalAndOffer)
            .catch((error) => {
              console.log(error);
            });
        }
      } catch (error) {
        console.log(error);
      }
    },
    setLocalAndAnswer(sessionDescription) {
      this.rtcPeerConnection.setLocalDescription(sessionDescription).then(() => {
        console.log("setLocalDescription完毕");
      });
      const id= this.sessionData.id|| ""
      this.socketed.send(
        JSON.stringify({
          type: this.TYPE_COMMAND_ANSWER,
          data: {
            //操作员工号
            from: this.userId,
            //车道号
            to: id,
            session_id: this.userId + "-" + id,
            //roomId: roomId,
            description: sessionDescription,
          },
        })
      );
    },
    setLocalAndOffer(sessionDescription) {
      try {
        this.rtcPeerConnection.setLocalDescription(sessionDescription).then(() => {
          console.log("setLocalDescription完毕");
        });
      } catch (error) {
        console.log(error);
      }
      const id= this.sessionData.id|| ""
      this.socketed.send(
        JSON.stringify({
          type: this.TYPE_COMMAND_OFFER,
          data: {
            //操作员工号
            from: this.userId,
            //车道号
            to: id,
            media: "video",
            session_id: this.userId + "-" + id,
            //roomId: roomId,
            description: {
              type: sessionDescription.type,
              sdp: sessionDescription.sdp,
            },
          },
        })
      )
    },
    onIceCandidate(event) {
      const _this = this
      const id= this.sessionData.id|| ""
      if (event.candidate) {
        setTimeout(() => {
          _this.socketed.send(
            JSON.stringify({
              type: _this.TYPE_COMMAND_CANDIDATE,
              data: {
                from: _this.userId,
                to: id,
                session_id: _this.userId + "-" + id,
                candidate: {
                  sdpMid: event.candidate.sdpMid,
                  sdpMLineIndex: event.candidate.sdpMLineIndex,
                  candidate: event.candidate.candidate,
                },
              },
            })
          );
        }, 1000);
      }
    },
    onTrack(event) {
      let remoteMediaStream = event.streams[0];
      let remoteVideo = document.getElementById("remoteVideo");
      try {
        remoteVideo.srcObject = remoteMediaStream;
        console.log(remoteMediaStream);
        setTimeout(function () {
          remoteVideo.play();
        }, 200);
      } catch (error) {
        console.log(error);
      }
    },
    cutStation() { //切换上下工位
      if (this.socketed) {
        const id= this.sessionData.id|| ""
        this.socketed.send(JSON.stringify({
          type: 'gala_message',
          data: {
            from: this.userId,
            to: id,
            type: "position",
            value: this.stationVlaue == 'up' ? 'up' : 'down'
          }
        }))
        this.stationVlaue == 'up' ? this.stationVlaue = 'up' : this.stationVlaue = 'down'
      }
    }

mounted的中调用connection 就可以了文章来源地址https://www.toymoban.com/news/detail-637881.html

到了这里,关于webRCT实时语音视频通话 结合 vue使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebRTC音视频通话-WebRTC本地视频通话使用ossrs服务搭建

    iOS开发-ossrs服务WebRTC本地视频通话服务搭建 之前开发中使用到了ossrs,这里记录一下ossrs支持的WebRTC本地服务搭建。 ossrs是什么呢? SRS(Simple Realtime Server)是一个简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT等多种实时流媒体协议。 官网地址:https://ossrs.net/lt

    2024年02月12日
    浏览(43)
  • 解决苹果Safari 浏览器下html不能自动播放声音和视频的问题-实时语音通话功能【唯一客服】...

    在实现我的客服系统中,实时语音通话功能的时候,如果想自动播放音视频流,在苹果设备上遇到了问题。 苹果浏览器(Safari)在默认情况下不允许声音在背景里自动播放。这是出于用户体验和隐私方面的考虑,避免在用户没有意识到的情况下自动播放声音。 解决办法是 iOS

    2024年02月12日
    浏览(126)
  • WebRTC实战-第二章-使用WebRTC实现音视频通话

    、 什么是WebRTC|WebRTC入门到精通必看|快速学会音视频通话原理|WebRTC超全资料分享FFmpeg/rtmp/hls/rtsp/SRS WebRTC **WebRTC详细指南** http://www.vue5.com/webrtc/webrtc.html WEBRTC三种类型(Mesh、MCU 和 SFU)的多方通信架构 WebRTC API包括媒体捕获,音频和视频编码和解码,传输层和会话管理 。 假设

    2023年04月12日
    浏览(50)
  • Windows7中使用SRS集成音视频一对一通话

    SRS早就具备了SFU的能力,比如一对一通话、多人通话、直播连麦等等。在沟通中,一对一是常用而且典型的场景, 让我们一起来看看如何用SRS做直播和RTC一体化的一对一通话。 一、启动windows7-docker  二、拉取SRS镜像 执行命令:docker pull ossrs/srs:4 使用docker images查看当前镜像列

    2024年02月16日
    浏览(53)
  • C++/Qt音视频通话开发MetaRTC源码解读,coturn穿透stun的使用

    本章内容解读MetaRTC开源代码,无任何二次开发,用于学习交流。 MetaRTC是国人开发的开源项目,适用各种场景音视频二次开发,可以去git阅读README,我们使用相对成熟的版本测试: Release v5.0-b4。 之前的demo是在同一个局域网的条件下,sdp交换IP和端口后就可以收发音视频数据

    2023年04月18日
    浏览(45)
  • WebRTC音视频通话(二)简单音视频通话

    本篇不详细介绍websocket,只针对websocket整合rtc。 webrtc是P2P通信,也就是实际交流的 只有两个人 ,而要建立通信,这两个人需要 交换一些信息来保证通信安全 。而且, webrtc必须通过ssh加密 ,也就是使用https协议、wss协议。 借用一幅图 1.1 创建端点的解析 以下解析不包括we

    2023年04月09日
    浏览(58)
  • WebRTC音视频通话-实现iOS端调用ossrs视频通话服务

    WebRTC音视频通话-实现iOS端调用ossrs视频通话服务 之前搭建ossrs服务,可以查看:https://blog.csdn.net/gloryFlow/article/details/132257196 这里iOS端使用GoogleWebRTC联调ossrs实现视频通话功能。 iOS端端效果图 ossrs效果图 WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站

    2024年02月13日
    浏览(54)
  • WebRTC音视频通话-RTC直播本地视频及相册视频文件

    WebRTC音视频通话-RTC直播本地视频及相册视频文件 WebRTC音视频通话-RTC直播本地视频文件效果图如下 WebRTC音视频通话-RTC直播本地视频文件时候,用到了AVPlayer、CADisplayLink。 AVPlayer是什么? AVPlayer是基于AVFoundation框架的一个类,很接近底层,灵活性强,可以自定义视频播放样式

    2024年02月13日
    浏览(48)
  • Android之 集成音视频通话

    一,背景 1.1 最近接收一个即时通讯二开项目,即时通讯部分用的XMPP协议,音视频则是集成的国外的开源免费库jitsi-meet-sdk-2.4.0-4.aar,是基于WebRTC的开源框架。但客户想要微信那种页面的排版,后来经研究jitsi是不能修改UI的,UI部分是用混合框架ReactNative写的,这样难度就大了

    2024年02月12日
    浏览(60)
  • WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机

    WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机 在之前已经实现了WebRTC调用ossrs服务,实现直播视频通话功能。但是在使用过程中,RTCCameraVideoCapturer类提供的方法不能修改及调节相机的灯光等设置,那就需要自定义RTCVideoCapturer自行采集画面了。 iOS端WebRTC调用ossrs相关,实现

    2024年02月12日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包