首页 > 其他分享 >WebRTC快速上手,建立时通信流程

WebRTC快速上手,建立时通信流程

时间:2024-10-20 16:18:00浏览次数:7  
标签:信令 candidate offer 流程 通信 pc error answer WebRTC

目录


媒体捕获

首先,我们需要获取用户的媒体设备(通常是摄像头和麦克风)的视频和音频流。

async function getMediaStream() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    return stream;
  } catch (error) {
    console.error('Error accessing media devices', error);
  }
}

创建RTCPeerConnection

接下来,创建RTCPeerConnection实例,这是WebRTC的核心,用于管理连接的生命周期和媒体流的传输。

const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] // 使用Google STUN服务器
});

// 当远程视频流被添加时,将其显示在页面上
pc.ontrack = event => {
  const remoteVideo = document.getElementById('remoteVideo');
  remoteVideo.srcObject = event.streams[0];
};

// 处理ICE候选
pc.onicecandidate = event => {
  if (event.candidate) {
    // 通过信令发送ICE候选给对方
    sendToServer({ type: 'candidate', candidate: event.candidate });
  }

};

添加本地媒体流

将获取到的本地媒体流添加到RTCPeerConnection实例中。

const localStream = await getMediaStream();
document.getElementById('localVideo').srcObject = localStream;

localStream.getTracks().forEach(track => {
  pc.addTrack(track, localStream);
});

信令交互

WebRTC应用需要自定义信令机制来交换SDP信息和ICE候选。这里以一个简化的示例说明如何处理offer和answer的交换。

发起呼叫方(Offerer)
async function createOffer() {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // 通过信令发送offer给对方
    sendToServer({ type: 'offer', sdp: pc.localDescription });
  } catch (error) {
    console.error('Error creating offer', error);
  }
}
接收呼叫方(Answerer)
function handleOffer(offer) {
  pc.setRemoteDescription(new RTCSessionDescription(offer));
  
  pc.createAnswer()
    .then(answer => {
      pc.setLocalDescription(answer);
      // 通过信令发送answer给对方
      sendToServer({ type: 'answer', sdp: answer });
    })
    .catch(error => console.error('Error creating answer', error));
}

function handleCandidate(candidate) {
  pc.addIceCandidate(new RTCIceCandidate(candidate));
}

信令服务的实现

这里假设使用WebSocket作为信令通道,实际应用中需要根据具体服务端逻辑实现。

let socket; // 假设WebSocket已连接

function sendToServer(message) {
  socket.send(JSON.stringify(message));
}

socket.addEventListener('message', event => {
  const data = JSON.parse(event.data);
  switch (data.type) {
    case 'offer':
      handleOffer(data.sdp);
      break;
    case 'answer':
      pc.setRemoteDescription(new RTCSessionDescription(data.sdp));
      break;
    case 'candidate':
      handleCandidate(data.candidate);
      break;
    default:
      console.log('Unknown message', data);
  }
});

错误处理

在WebRTC应用中,全面的错误处理机制是必不可少的,以确保用户能够获得良好的体验并及时了解问题所在。以下是一些关键环节的错误处理示例:

pc.onnegotiationneeded = async e => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    sendToServer({ type: 'offer', sdp: pc.localDescription });
  } catch (err) {
    console.error("Error during negotiation", err);
  }
};

pc.oniceconnectionstatechange = e => {
  switch(pc.iceConnectionState) {
    case "disconnected":
    case "failed":
      console.log("Connection failed or disconnected");
      // 可能需要重连逻辑或提示用户
      break;
    case "closed":
      console.log("Connection closed");
      break;
    default:
      // 其他状态,如checking, connected等
      break;
  }
};

// 示例:处理getUserMedia的错误
async function getMediaStream() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    return stream;
  } catch (error) {
    console.error('Error accessing media devices', error);
    alert("无法访问您的媒体设备,请检查权限设置。");
  }
}

连接状态监测

WebRTC提供了多种事件监听器来监测连接状态,如oniceconnectionstatechange、onnegotiationneeded、onsignalingstatechange等。通过监听这些事件,开发者可以实时响应连接的变化,比如在连接断开时尝试重连或向用户展示错误信息。

媒体流的停止和重连
停止本地媒体流可以通过调用MediaStreamTrack.stop()方法实现,而重连则通常涉及到重新创建RTCPeerConnection、重新获取媒体流和重新交换SDP信息。

// 停止本地媒体流
localStream.getTracks().forEach(track => track.stop());

// 重连逻辑可能需要重新初始化RTCPeerConnection、获取媒体流、交换offer-answer等
async function reconnect() {
  pc.close(); // 关闭现有连接
  pc = new RTCPeerConnection(config);
  // 重复之前的设置过程,如添加track、设置事件监听器等
}

使用成熟库简化开发

  • Adapter.js:这是一个官方推荐的库,用于解决浏览器之间的WebRTC API兼容性问题。只需在项目中引入Adapter.js,它会自动修补API差异,使得开发者可以使用统一的API编写代码。

  • SimpleWebRTC:这是一个更高级的库,提供了更高层次的抽象,简化了WebRTC的很多复杂操作,如自动处理信令、媒体流管理、房间管理等。使用SimpleWebRTC,开发者可以用更少的代码快速搭建视频聊天应用。

标签:信令,candidate,offer,流程,通信,pc,error,answer,WebRTC
From: https://blog.csdn.net/A1215383843/article/details/143094319

相关文章

  • Linux源码阅读: Linux内核启动的基本流程
    目录从硬件上电到BIOS从BIOS到BootloaderBootLoader加载流程mainReference进程管理从硬件上电到BIOS我们首先需要说的是实模式,实模式让所有软件访问到的地址都是最真实的物理地址。同时,软件可以不受限制的操作IO和内存。与之相对的是保护模式:进程访问到的全部都是虚......
  • SQL Injection | MySQL 手工注入全流程
    0x01:MySQL手工注入——理论篇手工注入MySQL数据库,一般分为以下五个阶段,如下图所示:第一阶段-判断注入点:在本阶段中,我们需要判断注入点的数据类型(数字型、字符型、搜索型、XX型)与后端查询方式,并使用对应的SQL语句进行测试,判断出目标是否存在注入点。第二阶段-......
  • 2.1.2 话题通信基本操作A(C++)
    需求:编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。分析:在模型实现中,ROSmaster不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:发布方接收方数据(此处为普通文本)流程:编写发布方实现;编写订阅......
  • so加载流程分析
    源码我的安卓版本:Pie9.0.0_r查看android源码的网站AndroidXRefAOSPXRefso的加载有两种方式,一种是在Java层加载,另一种是在Native层加载。Java层在Java层加载so的方式,这里有两种方式在源码的System.java类里System.load(“/data/data/app包名/lib/libnative-lib.so......
  • WebRTC学习五:从视频中提取图片
    系列文章目录第一篇基于SRS的WebRTC环境搭建第二篇基于SRS实现RTSP接入与WebRTC播放第三篇centos下基于ZLMediaKit的WebRTC环境搭建第四篇WebRTC学习一:获取音频和视频设备第五篇WebRTC学习二:WebRTC音视频数据采集第六篇WebRTC学习三:WebRTC音视频约束第七......
  • 从克隆项目到修改并上传到自己 GitHub 仓库的流程(包括私钥配置)
    从克隆项目到修改并上传到自己GitHub仓库的流程(包括私钥配置)生成SSH密钥如果还没有生成SSH密钥,可以通过以下命令生成:ssh-keygen-trsa-C"[email protected]"系统会提示你保存密钥的位置,通常保存在~/.ssh/id_rsa,如果不需要加密密码,直接按回车。添加SSH......
  • Django drf jwt token认证前后端使用流程
    在DjangoRestFramework(DRF)中使用JWT(JSONWebToken)进行认证时,前后端需要配合工作。下面是DRF使用JWT认证的一个基本流程。后端部分安装必要的库:需要安装djangorestframework和djangorestframework-simplejwt两个库。后者是处理JWT的工具。pipin......
  • SpringMVC执行流程
    SpringMVC执行流程文章目录SpringMVC执行流程1.Spring常用组件1.1DispatcherServlet:前端控制器1.2HandlerMapping:处理器映射器1.3Handler:处理器1.4HandlerAdapter:处理器适配器1.5ViewResolver:视图解析器1.6View:视图2.DispatcherServlet的初始化与生命周期2.1......
  • Kubernetes部署Prometheus并实现自定义指标HPA(安装、配置、实现全流程)
    1.安装kube-prometheusKube-Prometheus是一个开箱即用的监控解决方案,用于监控Kubernetes集群。它集成了Prometheus、Prometheus-Adapter、Alertmanager和一系列的导出器(exporters),使你能够轻松地收集和可视化集群中各种资源的监控数据。1.1克隆kube-prometheus仓库gitclon......
  • C++ WM\_COPYDATA 实现进程通信
    基于MFC用于存储数据的自定义结构体:structMSG_STRUCT{ wchar_tmsg[256];};发送端,发送按钮响应事件的代码voidCSendWM_COPYDATADlg::OnBnClickedSendmessage(){ MSG_STRUCTsmsg; GetDlgItemText(IDC_MESSAGE,smsg.msg,256); HWNDhTargetWnd=NULL; hTargetWnd=::Fi......