WebRTC从入门到实践 - 零基础教程
目录
WebRTC简介
基础概念
工作原理
开发环境搭建
基础实践
三个实战案例
常见问题解答
1. WebRTC简介
1.1 什么是WebRTC?
WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术。简单来说,它就是让浏览器提供实时通信的能力。
1.2 WebRTC能做什么?
视频聊天
语音通话
P2P文件传输
屏幕共享
在线教育
远程医疗
游戏数据传输
1.3 为什么选择WebRTC?
MediaStream:获取音视频流
RTCPeerConnection:建立点对点连接
RTCDataChannel:传输数据
2.2 信令服务器(Signaling Server)
会话控制信息
网络配置
媒体功能和设置
2.3 STUN/TURN服务器
防火墙限制
NAT类型不支持
STUN/TURN服务器配置错误
信令服务器未正确转发消息
7.2 媒体问题
Q: 为什么看不到视频/听不到声音? A: 检查:
使用合适的视频分辨率
启用视频编码(VP8/H.264)
合理控制带宽使用
使用合适的TURN服务器
7.4 调试技巧
WebRTC官方文档
MDN WebRTC指南
WebRTC示例
使用Chrome开发者工具
查看 chrome://webrtc-internals
检查ICE连接状态
监控网络数据传输
扩展阅读
摄像头/麦克风权限
设备是否正常工作
媒体流是否正确获取
轨道是否正确添加
7.3 性能问题
Q: 如何优化性能? A: 建议:
STUN:帮助获取公网IP
TURN:作为备用中继服务器
3. 工作原理
3.1 基本流程
3.2 连接建立过程
客户端A信令服务器客户端B发送offer转发offer发送answer转发answer建立P2P连接客户端A信令服务器客户端B
4. 开发环境搭建
4.1 基础环境准备
# 创建项目目录 mkdir webrtc-demo cd webrtc-demo # 初始化项目 npm init -y # 安装依赖 npm install express socket.io
4.2 服务器代码
// server.js // 引入 express 模块 const express = require('express'); // 创建 express 应用实例 const app = express(); // 创建 HTTP 服务器并将应用附加到服务器 const server = require('http').Server(app); // 引入 socket.io 并将其附加到服务器 const io = require('socket.io')(server); // 将静态文件目录设置为 'public' app.use(express.static('public')); // 当有客户端与服务器建立连接时触发 io.on('connection', socket => { // 监听客户端发送的 'join' 事件,加入指定的房间 socket.on('join', room => { socket.join(room); }); // 监听客户端发送的 'offer' 事件,转发 offer 给同一房间的其他客户端 socket.on('offer', data => { socket.to(data.room).emit('offer', data.offer); }); // 监听客户端发送的 'answer' 事件,转发 answer 给同一房间的其他客户端 socket.on('answer', data => { socket.to(data.room).emit('answer', data.answer); }); // 监听客户端发送的 'ice-candidate' 事件,转发 ICE 候选者给同一房间的其他客户端 socket.on('ice-candidate', data => { socket.to(data.room).emit('ice-candidate', data.candidate); }); }); // 服务器监听 3000 端口,启动服务器并在控制台输出提示信息 server.listen(3000, () => { console.log('Server running at http://localhost:3000'); });
4.3 前端基础结构
WebRTC Demo Start Call Hang Up
5. 基础实践
5.1 获取本地媒体流
async function getLocalStream() { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true }); document.getElementById('localVideo').srcObject = stream; return stream; } catch (err) { console.error('获取媒体流失败:', err); } }
5.2 建立点对点连接
// 创建RTCPeerConnection function createPeerConnection() { const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }; const pc = new RTCPeerConnection(configuration); // 添加媒体流轨道 localStream.getTracks().forEach(track => { pc.addTrack(track, localStream); }); // 处理远程流 pc.ontrack = event => { document.getElementById('remoteVideo').srcObject = event.streams[0]; }; return pc; }
6. 三个实战案例
6.1 视频聊天室
// 完整的视频聊天实现 const socket = io(); let pc; let localStream; async function startCall() { localStream = await getLocalStream(); pc = createPeerConnection(); // 创建并发送offer const offer = await pc.createOffer(); await pc.setLocalDescription(offer); socket.emit('offer', { offer, room: 'test-room' }); } socket.on('offer', async offer => { pc = createPeerConnection(); await pc.setRemoteDescription(offer); // 创建并发送answer const answer = await pc.createAnswer(); await pc.setLocalDescription(answer); socket.emit('answer', { answer, room: 'test-room' }); }); // 开始通话 document.getElementById('startButton').onclick = startCall;
6.2 文件传输
// 文件传输示例 let dataChannel; function setupDataChannel() { dataChannel = pc.createDataChannel('fileTransfer'); dataChannel.onmessage = event => { // 接收文件数据 const fileData = event.data; downloadFile(fileData); }; } function sendFile(file) { const reader = new FileReader(); reader.onload = e => { dataChannel.send(e.target.result); }; reader.readAsArrayBuffer(file); }
6.3 屏幕共享
// 屏幕共享示例 async function startScreenShare() { try { const stream = await navigator.mediaDevices.getDisplayMedia({ video: true }); document.getElementById('localVideo').srcObject = stream; // 替换视频轨道 const videoTrack = stream.getVideoTracks()[0]; const sender = pc.getSenders().find(s => s.track.kind === 'video'); sender.replaceTrack(videoTrack); } catch (err) { console.error('屏幕共享失败:', err); } }
7. 常见问题解答
7.1 连接问题
Q: 为什么建立不了连接? A: 常见原因:
作用:帮助双方建立连接
交换信息:
免费开源
实时性好
跨平台
支持P2P
安全性高
无需插件
2. 基础概念
2.1 核心组件
获取本地媒体流
创建对等连接
交换网络信息
交换媒体信息
建立连接传输数据