WebRTC项目一对一视频

开发步骤

1.客户端显示界面

2.打开摄像头并显示到页面

3.websocket连接

4.join、new-peer、resp-join信令实现

5.leave、peer-leave信令实现

6.offer、answer、candidate信令实现

7.综合调试和完善

1.客户端显示界面

复制代码
步骤:创建html页面
主要是input、button、video控件的布局。

2.打开摄像头并显示到页面

复制代码
function openLocalStream() {
    //初始化本地码流
    navigator.mediaDevices
    .getUserMedia({ //初始化本地码流信息
        audio: true,
        video: { width: 640, height: 480 }
    })
    .then(function (stream) { // 打开本地码流
        console.log('Open local stream');
        localVideo.srcObject = stream;
        localStream = stream;
    })
    .catch(function (e) { //错误cb
        alert("getUserMedia() error: " + e.name);
    });
}
document.getElementById('joinBtn').onclick = function () {
    console.log("加入按钮被点击");
    openLocalStream();
};


function closeLocalStream() {
    if (localStream) {
        localStream.getTracks().forEach(track => {
            track.stop();
        });
        localStream = null;
        localVideo.srcObject = null;
    }
}
document.getElementById('leaveBtn').onclick = function () {
    console.log("离开按钮被点击");
    closeLocalStream();
};

3.websocket连接

封装websocket

复制代码
class RTCEngine {
    constructor(wsUrl) {
        this.init(wsUrl);
    }

    init(wsUrl) {
        this.wsUrl = wsUrl;
        this.signaling = null;
    }

    onOpen() {
        console.log("websocket open");
    }

    onMessage(event) {
        console.log("onMessage: " + event.data);
    }

    onError(event) {
        console.log("onError: " + event.data);
    }

    onClose(event) {
        console.log("onClose -> code: " + event.code + ", reason: " + event.reason);
    }

    createWebSocket() {
        this.signaling = new WebSocket(this.wsUrl);
        this.signaling.onopen = () => this.onOpen();
        this.signaling.onmessage = ev => this.onMessage(ev);
        this.signaling.onerror = ev => this.onError(ev);
        this.signaling.onclose = ev => this.onClose(ev);
    }
}



import RTCEngine from './RTCEngineWS.js';
const rtce = new RTCEngine("ws://192.168.1.25:8099");
rtce.createWebSocket();

4.join、new-peer、resp-join overload信令设计

信令设计:

RTCEngineWS.js websocket封装类负责接收,发送消息以及连接状态管理。

signal.js 信令的设计集合

main.js 主逻辑

思路:(1)点击加入开妞;(2)响应加入按钮事件;(3)将join发送给服务器;(4)服务器 根据当前房间的人数

做处理,如果房间已经有人则通知房间里面的人有新人加入(newpeer),并通知自己房间里面是什么人(resp-join)。如果房间存在2个 则返回房间号人数已满

复制代码
var jsonMsg = {
    'cmd': 'join',
    'roomId': roomId,
    'uid': localUserId,
};
var jsonMsg = {
    'cmd': 'resp‐join',
    'remoteUid': remoteUid
};
var jsonMsg = {
   'cmd': 'new‐peer',
   'remoteUid': uid
};
var jsonMsg = {
    'cmd': 'overload',
};

5.leave、peer-leave 信令实现

思路:(1)点击离开按钮;(2)响应离开按钮事件;(3)将leave发送给服务器;(4)服

务器处理leave,将发送者删除并通知房间(peer leave)的其他人;(5)房间的其他人在客户

端响应peer leave事件。

复制代码
var jsonMsg = {
    'cmd': 'leave',
    'roomId': roomId,
    'uid': localUserId,
};
var jsonMsg = {
    'cmd': 'peer‐leave',
    'remoteUid': uid
};
var jsonMsg = {
    'cmd': 'peer‐leave',
    'remoteUid': uid
}; 

6.offer、answer、candidate信令实现

思路:

(1C)收到newpeer (handleRemoteNewPeer处理),作为发起者创建RTCPeerConnection,绑定事件响应函数,加入本地流;

(2C)创建offer sdp,设置本地sdp,并将offer sdp发送到服务器;

(3SSS)服务器收到offer sdp 转发给指定的remoteClient;

(4C)接收者收到offer,也创建RTCPeerConnection,绑定事件响应函数,加入本地流;

(5C)接收者设置远程sdp,并创建answer sdp,然后设置本地sdp并将answer sdp发送到服务器;

(6SSS)服务器收到answer sdp 转发给指定的remoteClient;

(7C)发起者收到answer sdp,则设置远程sdp;

(8C)发起者和接收者都收到ontrack回调事件,获取到对方码流的对象句柄;

(9)发起者和接收者都开始请求打洞,通过onIceCandidate获取到打洞信息(candidate)并发送给对方

(10)如果P2P能成功则进行P2P通话,如果P2P不成功则进行中继转发通话。

复制代码
offer、answer、candidate分别如下
var jsonMsg = {
    'cmd': SIGNAL_TYPE_OFFER,
    'roomId': roomId,
    'uid': localUserId,
    'remoteUid': remoteUserId,
    'msg': JSON.stringify(session)
};
var jsonMsg = {
    'cmd': SIGNAL_TYPE_ANSWER,
    'roomId': roomId,
    'uid': localUserId,
    'remoteUid': remoteUserId,
    'msg': JSON.stringify(session)
};
var jsonMsg = {
    'cmd': SIGNAL_TYPE_CANDIDATE,
    'roomId': roomId,
    'uid': localUserId,
    'remoteUid': remoteUserId,
    'msg': JSON.stringify(event.candidate)
};

7.综合调试和完善

正常退出和关闭工作

思路:

(1)点击离开时,要将本地摄像头和麦克风关闭; 要将RTCPeerConnection关闭(close);

(2)检测到客户端退出时,服务器再次检测该客户端是否已经退出房间。

总结

信令服务器设计,主要是转发客户端发来的消息到对端,根据类型进行转发。

学习资料分享

0voice · GitHub

相关推荐
aqi002 分钟前
FFmpeg开发笔记(七十七)Android的开源音视频剪辑框架RxFFmpeg
android·ffmpeg·音视频·流媒体
慢行的骑兵2 小时前
Android音视频探索之旅 | CMake基础语法 && 创建支持Ffmpeg的Android项目
ffmpeg·音视频
Just_Paranoid2 小时前
华为云Flexus+DeepSeek征文|基于Dify构建音视频内容转录工作流
华为云·音视频·dify·maas·deepseek·flexusx
go54631584653 小时前
修改Spatial-MLLM项目,使其专注于无人机航拍视频的空间理解
人工智能·算法·机器学习·架构·音视频·无人机
大胡子大叔6 小时前
webrtc-streamer视频流播放(rstp协议h264笔记)
笔记·webrtc·rtsp·webrtc-streamer
叹一曲当时只道是寻常6 小时前
Softhub软件下载站实战开发(十):实现图片视频上传下载接口
golang·go·音视频
音视频牛哥8 小时前
计算机视觉的新浪潮:扩散模型(Diffusion Models)技术剖析与应用前景
人工智能·计算机视觉·ai·音视频·实时音视频·扩散模型
电子科技圈9 小时前
SmartDV推出先进的H.264和H.265视频编码器和解码器IP
音视频·h.265·h.264
feiyangqingyun11 小时前
Qt音视频开发技巧/推流带旋转角度/rtsprtmp推流/保存文件到MP4/拉流解析旋转角度
qt·音视频·qt旋转角度推流
Despacito0o11 小时前
ESP32-s3摄像头驱动开发实战:从零搭建实时图像显示系统
人工智能·驱动开发·嵌入式硬件·音视频·嵌入式实时数据库