webrtc实现点对点视频通讯
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webrtc</title>
<style>
#yours{
width:300px;
position:absolute;
top:200px;
left:100px;
}
#theirs{
width:300px;
position:absolute;
top:200px;
left:400px;
}
</style>
</head>
<body>
<button onclick="createOffer()">建立连接</button>
<video id="yours" autoplay></video>
<video id="theirs" autoplay></video> </body> <script src="./lib/jquery.min.js"></script>
<script src="./lib/webrtc.js"></script> </html>
webrtc.js
var websocket;
function randomNum(minNum,maxNum){
switch(arguments.length){
case :
return parseInt(Math.random()*minNum+,);
break;
case :
return parseInt(Math.random()*(maxNum-minNum+)+minNum,);
break;
default:
return ;
break;
}
}
const userid = 'user' + randomNum(,);
function hasUserMedia() {
navigator.getUserMedia = navigator.getUserMedia || navigator.msGetUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
return !!navigator.getUserMedia;
}
function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.msRTCPeerConnection;
return !!window.RTCPeerConnection;
}
var yourVideo = document.getElementById("yours");
var theirVideo = document.getElementById("theirs");
var Connection;
function startPeerConnection() {
//return;
var config = {
'iceServers': [
//{ 'urls': 'stun:stun.xten.com:3478' },
//{ 'urls': 'stun:stun.voxgratia.org:3478' },
{ 'url': 'stun:stun.l.google.com:19302' }
]
};
config = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' }
],
//sdpSemantics: 'unified-plan'
};
// {
// "iceServers": [{
// "url": "stun:stun.1.google.com:19302"
// }]
// };
Connection = new RTCPeerConnection(config);
Connection.onicecandidate = function(e) {
console.log('onicecandidate');
if (e.candidate) {
websocket.send(JSON.stringify({
"userid":userid,
"event": "_ice_candidate",
"data": {
"candidate": e.candidate
}
}));
}
}
Connection.onaddstream = function(e) {
console.log('onaddstream');
//theirVideo.src = window.URL.createObjectURL(e.stream);
theirVideo.srcObject = e.stream;
}
}
createSocket();
startPeerConnection();
if (hasUserMedia()) {
navigator.getUserMedia({ video: true, audio: false },
stream => {
yourVideo.srcObject = stream;
window.stream = stream;
Connection.addStream(stream)
},
err => {
console.log(err);
})
}
function createOffer(){
//发送offer和answer的函数,发送本地session描述
Connection.createOffer().then(offer => {
Connection.setLocalDescription(offer);
websocket.send(JSON.stringify({
"userid":userid,
"event": "offer",
"data": {
"sdp": offer
}
}));
});
}
function createSocket(){
//websocket = null;
websocket = new WebSocket('wss://www.ecoblog.online/wss');
eventBind();
};
function eventBind() {
//连接成功
websocket.onopen = function(e) {
console.log('连接成功')
};
//server端请求关闭
websocket.onclose = function(e) {
console.log('close')
};
//error
websocket.onerror = function(e) {
};
//收到消息
websocket.onmessage = (event)=> {
if(event.data == "new user") {
location.reload();
} else {
var json = JSON.parse(event.data);
console.log('onmessage: ', json);
if(json.userid !=userid){
//如果是一个ICE的候选,则将其加入到PeerConnection中,否则设定对方的session描述为传递过来的描述
if(json.event === "_ice_candidate"&&json.data.candidate) {
Connection.addIceCandidate(new RTCIceCandidate(json.data.candidate));
}else if(json.event ==='offer'){
Connection.setRemoteDescription(json.data.sdp);
Connection.createAnswer().then(answer => {
Connection.setLocalDescription(answer);
console.log(window.stream)
websocket.send(JSON.stringify({
"userid":userid,
"event": "answer",
"data": {
"sdp": answer
}
}));
})
}else if(json.event ==='answer'){
Connection.setRemoteDescription(json.data.sdp);
console.log(window.stream)
}
}
}
};
}
建立连接的过程:
1⃣️两个浏览器都打开该页面,连接到同一个socket('wss://www.ecoblog.online/wss');
注意:webrtc只能在localhost或者https下使用,所以线上环境的话,我们的socket服务以及html页面都必须是要有https证书的;
对于wss,利用反向代理,在nginx的站点配置下如下配置/wss:

正如你所看到的那样,socket服务开在12345端口,所以还要去阿里云网站开一个这个端口的出入站规则;
另外centos的防火墙对该端口开放,或者直接关闭防火墙(自行百度)
socket服务写得比较简陋,但已够用,功能就是把收到的信息发给当前连接的所有c端

2⃣️两个c端已经和socket建立连接,然后任意其中一端点击“建立连接”
此时点击建立连接的端就是offer(携带信号源信息),发给另外一个端,另外一个端收到offer之后,发出响应answer(携带信号源信息),offer端收到answer端信息进行存储;
这样每个端都有了自己的信息和对方的信息,
3⃣️candidata信息的发送
其实这块,网上有的说法是offer发出answer发出后设置了localDescription和remoteDescription后就会触发onicecandidate,但是我测试的时候貌似没有,所以
我这里是在获取摄像头信息后通过
Connection.addStream(stream)
来触发Connection.onicecandidate,在这个事件监听的回调里,发出自身端的candidata给对方,如此一来,双方都有了对方的localDescription、remoteDescription和candidata;
三者齐全之后,就会触发Connection.onaddstream,这样,直接通过:
theirVideo.srcObject = e.stream;
把流写到video里面去,这样就能展示对方的视频信息了:
但是这样,只能在局域网内使用,如果要在公网使用的话,还要一个穿透服务器,网上找的一些免费的好像都不能用了?还是说我写得有问题?
具体的可百度,webrtc搭建stun服务器
webrtc实现点对点视频通讯的更多相关文章
- webrtc笔记(3): 多人视频通讯常用架构Mesh/MCU/SFU
问题:为什么要搞这么多架构? webrtc虽然是一项主要使用p2p的实时通讯技术,本应该是无中心化节点的,但是在一些大型多人通讯场景,如果都使用端对端直连,端上会遇到很带宽和性能的问题,所以就有了下图 ...
- 使用WebRTC搭建前端视频聊天室——点对点通信篇
WebRTC给我们带来了浏览器中的视频.音频聊天体验.但个人认为,它最实用的特性莫过于DataChannel——在浏览器之间建立一个点对点的数据通道.在DataChannel之前,浏览器到浏览器的数据 ...
- 使用WebRTC搭建前端视频聊天室——信令篇
博客原文地址 建议看这篇之前先看一下使用WebRTC搭建前端视频聊天室——入门篇 如果需要搭建实例的话可以参照SkyRTC-demo:github地址 其中使用了两个库:SkyRTC(github地址 ...
- JMeter扩展Java请求实现WebRTC本地音视频推流压测脚本
WebRTC是Web Real-Time Communication缩写,指网页即时通讯,是一个支持Web浏览器进行实时语音或视频对话的API,实现了基于网页的视频会议,比如声网的Agora Web ...
- 使用WebRTC搭建前端视频聊天室——数据通道篇
本文翻译自WebRTC data channels 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩展成 ...
- 使用WebRTC搭建前端视频聊天室
在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩展成多个数据中心.这种情况下很容易出现很高的延迟,同时难 ...
- WebRTC:一个视频聊天的简单例子
相关API简介 在前面的章节中,已经对WebRTC相关的重要知识点进行了介绍,包括涉及的网络协议.会话描述协议.如何进行网络穿透等,剩下的就是WebRTC的API了. WebRTC通信相关的API非常 ...
- WebRTC搭建前端视频聊天室——数据通道篇
本文翻译自WebRTC data channels 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩展成 ...
- springboot+kurento+coturn+contos的视频通讯服务搭建
springboot+kurento+coturn+contos的视频通讯服务搭建 服务器CentOS Linux release 7.9.2009 (Core) 本案例成功于20210628 1.默 ...
随机推荐
- css改变背景透明度
透明往往能产生不错的网页视觉效果,先奉上兼容主流浏览器的CSS透明代码:.transparent{filter:alpha(opacity=90); -moz-opacity:0.9; -khtml- ...
- json_decode 和 json_encode 区别
json_decode: json字符串转json对象json_encode: json对象转json字符串 json对象: { "id": 68, "order_no& ...
- Java-WebServiceUtil工具类
/** * Program : WebServiceUtil.java * Author : leigq * Create : 2010-11-12 上午09:02:05 * * Copyright ...
- java学习记录--ThreadLocal使用案例(转)
本文借由并发环境下使用线程不安全的SimpleDateFormat优化案例,帮助大家理解ThreadLocal. 最近整理公司项目,发现不少写的比较糟糕的地方,比如下面这个: public class ...
- SQL CASE Syntax
CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE ...
- Java进阶知识04 Struts2的基础配置详解
1.Struts2的原理/流程步骤 简单的理解: 1.客户端发送一个request请求,Tomcat服务器接收到的请求经过web.xml配置文件去处理,进入struts2的核心过滤器,从而进入s ...
- Python基础之Python语言类型
编程语言主要从以下几个角度进行分类: 编译型和解释型 静态语言和动态语言 强类型定义语言和弱类型定义语言 编译和解释的区别是什么? 编译器把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样 ...
- JavaWeb_(Hibernate框架)Hibernate中重要的api
Hibernate中重要的api Configuration SessionFactory Session(重点) Transaction 在Dao层中UserDao.java使用Hibernate向 ...
- Android学习_7/25
常用控件 Android控件使用规律:先定义id,再指定宽度和高度,然后适当加入一些控件特有的属性 1. TextView 在界面上显示一段文本 2. Button ...
- 一个服务器的Apache2.4.6配置多个域名
进入到Apache的配置文件:cd /etc/httpd/conf/http.conf 在后面添加: <VirtualHost *:80> # This first-listed virt ...