webrtc一对一通话

webrtc一对一通话


目录

  1. 一对一通话原理
  2. RTCPeerConnection
  3. 实现WebRTC音视频通话思路
  4. 部署到公网

1. 一对一通话原理

  1. 对于WebRTC应用开发人员而言,主要是关注RTCPeerConnection类,主要分为以下四块
    1. 信令设计;
    2. 媒体协商;
    3. 加入Stream/Track;
    4. 网络协商
      在这里插入图片描述
1. 信令协议设计
  1. 采用json封装格式

    1. join:加入房间
    2. resp-­join:当join房间后发现房间已经存在另一个人时则返回另一个人的uid;如果只有自己则不返回
    3. leave:离开房间,服务器收到leave信令则检查同一房间是否有其他人,如果有其他人则通知他有人离开
    4. new­-peer:服务器通知客户端有新人加入,收到new­peer则发起连接请求
    5. peer-­leave:服务器通知客户端有人离开
    6. offer:转发offer sdp
    7. answer:转发answer sdp
    8. candidate:转发candidate sdp
  2. join:加入房间

var jsonMsg = {
	'cmd': 'join',
	'roomId': roomId,
	'uid': localUserId,
};
  1. resp-­join:当join房间后发现房间已经存在另一个人时则返回另一个人的uid;如果只有自己则不返回
jsonMsg = {
	'cmd': 'resp‐join',
	'remoteUid': remoteUid
};
  1. leave:离开房间,服务器收到leave信令则检查同一房间是否有其他人,如果有其他人则通知他有人离开
var jsonMsg = {
	'cmd': 'leave',
	'roomId': roomId,
	'uid': localUserId,
};
  1. new­-peer:服务器通知客户端有新人加入,收到new­peer则发起连接请求
var jsonMsg = {
	'cmd': 'new‐peer',
	'remoteUid': uid
};
  1. peer-­leave:服务器通知客户端有人离开
var jsonMsg = {
	'cmd': 'peer‐leave',
	'remoteUid': uid
};
  1. offer:转发offer sdp
var jsonMsg = {
	'cmd': 'offer',
	'roomId': roomId,
	'uid': localUserId,
	'remoteUid':remoteUserId,
	'msg': JSON.stringify(sessionDescription)
};
  1. answer:转发answer sdp
var jsonMsg = {
	'cmd': 'answer',
	'roomId': roomId,
	'uid': localUserId,
	'remoteUid':remoteUserId,
	'msg': JSON.stringify(sessionDescription)
};
  1. candidate:转发candidate sdp
var jsonMsg = {
	'cmd': 'candidate',
	'roomId': roomId,
	'uid': localUserId,
	'remoteUid':remoteUserId,
	'msg': JSON.stringify(candidateJson)
};
2 媒体协商

在这里插入图片描述

1. createOffer
  1. 基本格式
    1. aPromise = myPeerConnection.createOffer([options]);
  2. [options]
var options = {
	offerToReceiveAudio: true, // 告诉另一端,你是否想接收音频,默认true
	offerToReceiveVideo: true, // 告诉另一端,你是否想接收视频,默认true
	iceRestart: false, // 是否在活跃状态重启ICE网络协商
};
  1. iceRestart:只有在处于活跃的时候,iceRestart=false才有作用。
  2. 测试:https://webrtc.github.io/samples/src/content/peerconnection/restart-ice/
2. createAnswer
  1. 基本格式
    1. aPromise = RTCPeerConnection .createAnswer([ options ]); 目前createAnswer的options是无效的。
3. setLocalDescription
  1. 基本格式
    1. aPromise = RTCPeerConnection .setLocalDescription(sessionDescription);
4. setRemoteDescription
  1. 基本格式
    1. aPromise = pc.setRemoteDescription(sessionDescription);
3. 加入Stream/Track
1. addTrack
  1. 基本格式
    1. rtpSender = rtcPeerConnection .addTrack(track,stream …);
  2. track:添加到RTCPeerConnection中的媒体轨(音频track/视频track)
  3. stream:getUserMedia中拿到的流,指定track所在的stream
4. 网络协商
1. addIceCandidate
  1. 基本格式:
    1. aPromise = pc.addIceCandidate(候选人);
  2. candidate
属性说明
candidate候选者描述信息
sdpMid与候选者相关的媒体流的识别标签
sdpMLineIndex在SDP中 m=的索引值
usernameFragment包括了远端的唯一标识
        var candidateJson = {
            'label': event.candidate.sdpMLineIndex,
            'id': event.candidate.sdpMid,
            'candidate': event.candidate.candidate
        };
  1. 注意Android和Web端的不同。

2. RTCPeerConnection

1. 构造函数:
  1. 语法:
pc = new RTCPeerConnection([ configuration ];
2. configuration可选
  1. bundlePolicy 一般用max­bundle
banlanced:音频与视频轨使用各自的传输通道
max­compat:每个轨使用自己的传输通道
max­bundle:都绑定到同一个传输通道
  1. iceTransportPolicy 一般用all
指定ICE的传输策略
relay:只使用中继候选者
all:可以使用任何类型的候选者
  1. iceServers
    1. 其由RTCIceServer组成,每个RTCIceServer都是一个ICE代理的服务器
属性含义
credential凭据,只有TURN服务使用
credentialType凭据类型,可以password或oauth
urls用于连接服中的ur数组
username用户名,只有TURN服务使用
  1. rtcpMuxPolicy 一般用require
    1. rtcp的复用策略,该选项在收集ICE候选者时使用
选项说明
negotiate收集RTCP与RTP复用的ICE候选者,如果RTCP能复用就与RTP复用,如果不能复用,就将他们单独使用
require只能收集RTCP与RTP复用的ICE候选者,如果RTCP不能复用,则失败
3. 重要事件
  1. onicecandidate:收到候选者时触发的事件
  2. ontrack:获取远端流
  3. onconnectionstatechange PeerConnection的连接状态,参考:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
pc.onconnectionstatechange = function(event) {
	switch(pc.connectionState) {
		case "connected":
			// The connection has become fully connected
			break;
		case "disconnected":
		case "failed":
			// One or more transports has terminated unexpectedly or in an error
			break;
		case "closed":
			// The connection has been closed
		break;
		}
}
  1. oniceconnectionstatechange ice连接事件 具体参考:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState

3. 实现WebRTC音视频通话

  1. 开发步骤
    1. 客户端显示界面
    2. 打开摄像头并显示到页面
    3. websocket连接
    4. join、new­peer、resp­join信令实现
    5. leave、peer­leave信令实现
    6. offer、answer、candidate信令实现
    7. 综合调试和完善
1. 客户端显示界面
  1. 步骤:创建html页面
  2. 主要是input、button、video控件的布局。
2. 打开摄像头并显示到页面
3. websocket连接
4. join、new­peer、resp­join信令实现
  1. 思路:
    1. 点击加入按钮;
    2. 响应加入按钮事件;
    3. 将join发送给服务器;
    4. 服务器根据当前房间的人数做处理,如果房间已经有人则通知房间里面的人有新人加入(new­peer),并通知自己房间里面是什么人(respjoin)
5. leave、peer­leave信令实现
  1. 思路:
    1. 点击离开按钮;
    2. 响应离开按钮事件;
    3. 将leave发送给服务器;
    4. 服务器处理leave,将发送者删除并通知房间(peer­leave)的其他人;
    5. 房间的其他人在客户端响应peer­leave事件
6. offer、answer、candidate信令实现
  1. 思路:
    1. 收到new­peer (handleRemoteNewPeer处理),作为发起者创建RTCPeerConnection,绑定事件响应函数,加入本地流;
    2. 创建offer sdp,设置本地sdp,并将offer sdp发送到服务器;
    3. 服务器收到offer sdp 转发给指定的remoteClient;
    4. 接收者收到offer,也创建RTCPeerConnection,绑定事件响应函数,加入本地流;
    5. 接收者设置远程sdp,并创建answer sdp,然后设置本地sdp并将answer sdp发送到服务器;
    6. 服务器收到answer sdp 转发给指定的remoteClient;
    7. 发起者收到answer sdp,则设置远程sdp;
    8. 发起者和接收者都收到ontrack回调事件,获取到对方码流的对象句柄;
    9. 发起者和接收者都开始请求打洞,通过onIceCandidate获取到打洞信息(candidate)并发送给对方
    10. 如果P2P能成功则进行P2P通话,如果P2P不成功则进行中继转发通话。
7. 综合调试和完善
  1. 思路:
    1. 点击离开时,要将RTCPeerConnection关闭(close);
    2. 点击离开时,要将本地摄像头和麦克风关闭;
    3. 检测到客户端退出时,服务器再次检测该客户端是否已经退出房间。
    4. RTCPeerConnection时传入ICE server的参数,以便当在公网环境下可以进行正常通话。
      在这里插入图片描述
  2. 启动coturn,安装:ubantu安装coturn穿透服务器
# nohup是重定向命令,输出都将附加到当前目录的 nohup.out 文件中; 命令后加 & ,后台执行起来后按
ctr+c,不会停止
sudo nohup turnserver ‐L 0.0.0.0 ‐a ‐u test:test ‐v ‐f ‐r nort.gov &
# 前台启动
sudo turnserver ‐L 0.0.0.0 ‐a ‐u test:test ‐v ‐f ‐r nort.gov
#然后查看相应的端口号3478是否存在进程
sudo lsof ‐i:3478
  1. 设置configuration,先设置为relay中继模式,只有relay中继模式可用的时候,才能部署到公网去(部署到公网后也先测试relay)。
	var defaultConfiguration = {
        bundlePolicy: "max-bundle",
        rtcpMuxPolicy: "require",
        iceTransportPolicy:"relay",//relay 或者 all
        // 修改ice数组测试效果,需要进行封装
        iceServers: [
            {
                "urls": [
                    "turn:8.141.75.248:3478?transport=udp",
                    "turn:8.141.75.248:3478?transport=tcp"       // 可以插入多个进行备选
                ],
                "username": "test",
                "credential": "test"
            },
            {
                "urls": [
                    "stun:8.141.75.248:3478"
                ]
            }
        ]
    };

    pc = new RTCPeerConnection(defaultConfiguration);
  1. relay中继网络状况,命令:sudo sar -n DEV 1
    5.
  2. 局域网P2P
    在这里插入图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值