WebRTC简介及应用

WebRTC(Web Real-Time Communication)是一种支持浏览器和移动设备 进行实时音视频通信的技术,无需安装插件或额外的软件。它是一个开放标准,最初由Google推动,并被W3C(万维网联盟)和IETF(互联网工程任务组)标准化。

WebRTC 的核心功能:

  1. 音视频采集(获取本地摄像头、麦克风)

  2. 音视频编解码(支持VP8/VP9/H.264等视频编码,Opus/G.711等音频编码)

  3. P2P(点对点)传输(通过UDP和NAT穿透技术进行低延迟通信)

  4. 数据通道(DataChannel)(可用于传输文本、文件等数据)

WebRTC 的主要 API:

  • getUserMedia:获取本地音视频流

  • RTCPeerConnection:建立点对点连接

  • RTCDataChannel:进行P2P数据传输

WebRTC 的应用场景:

  • 视频通话(如 Google Meet、Zoom)

  • 直播推流(结合 WebRTC + Media Server)

  • 远程协作(如 Google Docs 的多人编辑)

  • 在线教育、远程医疗

  • 物联网(IoT)设备的远程控制

在 Vue 2 前端项目中使用 WebRTC,可以实现视频通话、音视频流传输、屏幕共享等功能。以下是 WebRTC 在 Vue 2 项目中的基本实现步骤:


1. WebRTC 基本概念

WebRTC 提供了三个核心 API:

  • getUserMedia():获取摄像头、麦克风权限

  • RTCPeerConnection:建立 P2P 连接,传输音视频

  • RTCDataChannel:传输文本、文件等数据

创建 WebRTC.vue 组件

javascript 复制代码
<template>
  <div>
    <h2>WebRTC 视频采集</h2>
    <video ref="localVideo" autoplay playsinline></video>
    <button @click="startCamera">启动摄像头</button>
    <button @click="stopCamera">关闭摄像头</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      localStream: null,
    };
  },
  methods: {
    async startCamera() {
      try {
        this.localStream = await navigator.mediaDevices.getUserMedia({
          video: true,
          audio: true,
        });
        this.$refs.localVideo.srcObject = this.localStream;
      } catch (error) {
        console.error("获取摄像头失败:", error);
      }
    },
    stopCamera() {
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => track.stop());
        this.localStream = null;
      }
    },
  },
};
</script>

✅ 效果 :点击按钮可以打开/关闭摄像头,并在 <video> 组件中显示

实现 WebRTC P2P 连接

如果想要实现点对点(P2P)通信 ,需要使用 RTCPeerConnection,并结合 WebSocket / Socket.io 进行信令交换。

创建 PeerConnection.vue 组件

javascript 复制代码
<template>
  <div>
    <h2>WebRTC P2P 视频通话</h2>
    <video ref="localVideo" autoplay playsinline></video>
    <video ref="remoteVideo" autoplay playsinline></video>
    <button @click="startCall">开始通话</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      localStream: null,
      peerConnection: null,
      remoteStream: null,
    };
  },
  methods: {
    async startCall() {
      // 1. 获取本地视频流
      this.localStream = await navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true,
      });
      this.$refs.localVideo.srcObject = this.localStream;

      // 2. 创建 RTCPeerConnection
      this.peerConnection = new RTCPeerConnection();

      // 3. 添加本地流到 PeerConnection
      this.localStream.getTracks().forEach(track => {
        this.peerConnection.addTrack(track, this.localStream);
      });

      // 4. 监听远程流
      this.peerConnection.ontrack = event => {
        if (!this.remoteStream) {
          this.remoteStream = new MediaStream();
          this.$refs.remoteVideo.srcObject = this.remoteStream;
        }
        this.remoteStream.addTrack(event.track);
      };

      // 5. 创建 offer(本地 SDP)
      const offer = await this.peerConnection.createOffer();
      await this.peerConnection.setLocalDescription(offer);

      console.log("本地 SDP:", offer);
      // 这里需要使用 WebSocket / Socket.io 发送 SDP 给远程端
    },
  },
};
</script>

✅ 效果:

  • 获取本地视频流,并在 <video> 中播放

  • 创建 WebRTC 连接,并监听远程视频流

  • 生成 SDP(用于信令交换)

信令服务器(使用 WebSocket)

WebRTC 需要信令服务器 来交换 SDP 和 ICE 候选信息。可以使用 WebSocket 或 Socket.io 来实现:

后端(Node.js + WebSocket)
javascript 复制代码
const WebSocket = require("ws");
const server = new WebSocket.Server({ port: 3000 });

server.on("connection", ws => {
  ws.on("message", message => {
    console.log("收到消息:", message);
    server.clients.forEach(client => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
});

前端(Vue 使用 WebSocket 发送 SDP)

javascript 复制代码
const socket = new WebSocket("ws://localhost:3000");

this.peerConnection.onicecandidate = event => {
  if (event.candidate) {
    socket.send(JSON.stringify({ candidate: event.candidate }));
  }
};

socket.onmessage = async message => {
  const data = JSON.parse(message.data);
  if (data.sdp) {
    await this.peerConnection.setRemoteDescription(data.sdp);
    if (data.sdp.type === "offer") {
      const answer = await this.peerConnection.createAnswer();
      await this.peerConnection.setLocalDescription(answer);
      socket.send(JSON.stringify({ sdp: answer }));
    }
  } else if (data.candidate) {
    await this.peerConnection.addIceCandidate(data.candidate);
  }
};

✅ 效果:

  • 通过 WebSocket 服务器交换 SDP(Offer & Answer)

  • 传递 ICE 候选信息,实现 P2P 连接

3. WebRTC 进阶功能

✅ 屏幕共享

javascript 复制代码
const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
this.$refs.localVideo.srcObject = stream;

✅ 数据通道(P2P 传输文本/文件)

javascript 复制代码
const dataChannel = peerConnection.createDataChannel("chat");
dataChannel.onmessage = event => console.log("收到消息:", event.data);
dataChannel.send("Hello WebRTC!");

4. WebRTC 在项目中的应用,例如风电项目中的应用

你可以用 WebRTC 实现:

  • 风场监控:远程视频直播,实时监测风机状态

  • 远程协作:风机运维人员可以通过 WebRTC 进行视频通话,远程指导维修

  • 数据传输 :通过 WebRTC RTCDataChannel 低延迟传输风机运行数据

总结

需求 方案
采集摄像头 getUserMedia()
P2P 音视频 RTCPeerConnection
远程信令 WebSocket / Socket.io
屏幕共享 getDisplayMedia()
数据传输 RTCDataChannel

P2P是什么?

P2P(Peer-to-Peer,点对点)是一种去中心化的通信模式,指的是两个或多个设备可以直接通信,而无需依赖中间服务器。在 WebRTC 中,P2P 主要用于实现点对点音视频通话、文件传输等功能。

P2P vs 传统客户端-服务器模式

模式 特点 示例
客户端-服务器(Client-Server) 需要一个中心服务器来转发数据 HTTP 请求、WebSocket 聊天、直播服务器
P2P(Peer-to-Peer) 设备之间直接通信,无需服务器转发 WebRTC 视频通话、种子下载(BitTorrent)

✅ P2P 的优点:

  • 低延迟:数据直接传输,无需绕服务器

  • 节省带宽:不占用服务器流量

  • 去中心化:无须依赖单点服务器

❌ P2P 的挑战:

  • NAT 穿透:有些网络环境(如 4G、WiFi)可能会阻止 P2P 连接

  • 信令交换:需要 WebSocket / Socket.io 来建立连接


📌 P2P 在 WebRTC 中的作用

WebRTC 通过 RTCPeerConnection 实现 P2P 连接:

  1. 本地设备 获取摄像头/麦克风数据

  2. 信令服务器 交换 SDP 和 ICE 候选信息

  3. 建立 P2P 连接,直接传输音视频流

示例:P2P 连接代码

javascript 复制代码
const peer = new RTCPeerConnection();

// 监听 ICE 候选信息
peer.onicecandidate = event => {
  if (event.candidate) {
    sendToServer({ candidate: event.candidate });
  }
};

// 监听远程视频流
peer.ontrack = event => {
  document.querySelector("#remoteVideo").srcObject = event.streams[0];
};

// 发送音视频流
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => {
    document.querySelector("#localVideo").srcObject = stream;
    stream.getTracks().forEach(track => peer.addTrack(track, stream));
  });

✅ 实现效果:

  • 设备 A 和 B 通过 WebRTC 直接交换音视频数据,无需服务器转发

  • 服务器只负责信令交换 ,实际音视频数据是P2P 直连的

相关推荐
lovingsoft2 分钟前
Chrome Lighthouse 详解
前端·chrome
Qlly12 分钟前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝16 分钟前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦17 分钟前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡37 分钟前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI43 分钟前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95271 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人1 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring
内存过载1 小时前
用表格模拟甘特图:项目排期的土办法
前端·低代码
葡萄城技术团队1 小时前
用 SpreadJS 数据验证实现省市区三级联动
前端