简单的WebRTC例子
webrtc网上封装的很多,demo很多都是一个页面里实现的,今天实现了个完整的 , A 发视频给 B。
A offer.html作为offer
<!DOCTYPE html>
<html id="home" lang="en"> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<style> p { padding: 1em; } li {
border-bottom: 1px solid rgb(, , );
border-left: 1px solid rgb(, , );
padding: .5em;
} </style>
</head> <body> <script>
var mediaConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: false,
OfferToReceiveVideo: true
}
};
</script>
<script>
var offerer
,answererWin window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate; navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.URL = window.webkitURL || window.URL; window.iceServers = {
iceServers: [{
url: 'stun:23.21.150.121'
}
]
};
</script>
<script>
/* offerer */
function offererPeer(video_stream) {
offerer = new RTCPeerConnection(window.iceServers)
offerer.addStream(video_stream) offerer.onaddstream = function (event) {
// 本地显示video
} offerer.onicecandidate = function (event) {
if (!event || !event.candidate) return sendToP2({
'action' : 'candidate',
'candidate' :event.candidate
}) } offerer.createOffer(function (offer) {
offerer.setLocalDescription(offer)
sendToP2({
'action' : 'create',
'offer':offer
}) }, function() {}, mediaConstraints)
}
</script>
<script>
var video_constraints = {
mandatory: {},
optional: []
} function getUserMedia(callback) {
var n = navigator
n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia
n.getMedia({
audio: false,
video: video_constraints
}, callback, onerror) function onerror(e) {
alert(JSON.stringify(e, null, '\t'))
}
}
</script>
<script>
function sendToP2(data){
answererWin.postMessage(JSON.stringify(data) ,window.location) }
function receiveMessage(data){
data = JSON.parse(data.data)
switch ( data.action) {
case 'answer' :
offerer.setRemoteDescription(new RTCSessionDescription(data.answer))
break
case "candidate":
offerer.addIceCandidate(new RTCIceCandidate(data.candidate))
break }
console.log('msg' ,data)
} window.addEventListener("message", receiveMessage, false)
answererWin = window.open('answer.html' ,'t')
getUserMedia(function (video_stream) {
offererPeer(video_stream)
});
</script> </body> </html>
B answer.html 作为answer
<!DOCTYPE html>
<html id="home" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> </head> <body>
<article>
<div style="text-align:center;">
<div class="videos-container">
<video id="peer1-to-peer2" autoplay controls></video>
<h2>Offerer-to-Answerer</h2>
<h2>此页面刷新之后,必须重新刷新一下Offer页面</h2>
</div>
</div>
<script>
var mediaConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
</script>
<script>
var offerer, answerer;
var offererToAnswerer = document.getElementById('peer1-to-peer2'); window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate; navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
window.URL = window.webkitURL || window.URL; window.iceServers = {
iceServers: [{
url: 'stun:23.21.150.121'
}
]
};
</script>
<script>
/* answerer */ function answererPeer(offer, video_stream) {
answerer = new RTCPeerConnection(window.iceServers);
// answerer.addStream(video_stream); answerer.onaddstream = function (event) {
offererToAnswerer.src = URL.createObjectURL(event.stream);
offererToAnswerer.play();
}; answerer.onicecandidate = function (event) {
if (!event || !event.candidate) return;
sendToP1({
'action' : 'candidate',
'candidate' :event.candidate
})
//offerer.addIceCandidate(event.candidate);
}; answerer.setRemoteDescription(new RTCSessionDescription(offer));
answerer.createAnswer(function (answer) {
answerer.setLocalDescription(answer);
sendToP1({
'action' : 'answer' ,
'answer' : answer
})
//offerer.setRemoteDescription(answer);
}, function() {}, mediaConstraints);
} function receiveMessage(data){
data = JSON.parse(data.data)
console.log(data)
switch(data.action){
case "create":
answererPeer(data.offer , data.stream)
break
case "candidate":
answerer.addIceCandidate(new RTCIceCandidate(data.candidate))
break
}
}
window.addEventListener("message", receiveMessage, false) function sendToP1(data) {
opener.postMessage(JSON.stringify(data) , window.location)
}
</script> </article> </body> </html>
demo用 postMessage传递数据, 业务使用可以用websocket
A 先 createOffer ,生成的offer 供自己setLocalDescription ,并发给B
B 拿A的offer ,setRemoteDescription(offer) , 然后 createAnswer ,生成的answer 供自己setLocalDescription ,并发给A
A 拿B的answer 设置 setRemoteDescription(answer)
A onicecandidate 事件被触发 将得到的通道发给B
B addIceCandidate(new RTCIceCandidate(candidate)) 建立通道
B onicecandidate 事件被触发 将得到的通道发给A
A addIceCandidate(new RTCIceCandidate(candidate)) 建立通道
通道建立后视频就可以共享了
使用时,打开:offer.html 即可。
简单的WebRTC例子的更多相关文章
- 一个简单的CORBA例子
因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...
- 菜鸟学习Hibernate——简单的一个例子
一.Hibernate开发. 上篇博客已经为大家介绍了持久层框架的发展流程,持久层框架的种类. 为了能够使用Hibernate快速上手,我们先讲解一个简单的Hibernate应用实例hibernate ...
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下 我们先来实现一个简单的例子,hello world ...
- 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)
使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...
- 使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 ...
- 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...
- 一个简单的cmake例子
一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库 #在当前目录新建一个build目录,然后cd build ...
- vue双向数据绑定最最最最最简单直观的例子
vue双向数据绑定最最最最最简单直观的例子 一.总结 一句话总结:双向绑定既不仅model可以影响view的数据,view也可以影响model的数据 view model 数据 1.vue双向数据绑定 ...
- 一个最简单的JStorm例子
最简单的JStorm例子分为以下几个步骤: 1.生成Topology Map conf = new HashMp(); //topology所有自定义的配置均放入这个Map TopologyBuild ...
随机推荐
- 一个最简单的通过WireShark破解SSL加密网络数据包的方法
原文地址: http://article.yeeyan.org/view/530101/444688 一般来说,我们用WireShark来抓取包进行分析是没有多大问题的.但这里有个问题是,如果你碰到的 ...
- C#编程(三十八)----------运算符
原文链接: http://blog.csdn.net/shanyongxu/article/details/46877353 运算符 类别 运算符 算术运算符 + - * / 逻辑运算符 & ...
- python笔记33-python3连mysql增删改查
前言 做自动化测试的时候,注册了一个新用户,产生了多余的数据,下次用同一账号就无法注册了,这种情况该怎么办呢? 自动化测试都有个数据准备和数据清理的操作,如果因为此用例产生了多余的数据,就需要数据清理 ...
- mysql递归查询从子类ID查询所有父类
先来看数据表的结构如下: id name parent_id --------------------------- 1 Home 0 2 About ...
- 在LaTeX中使用颜色 Using colours in LaTeX
Using colours in LaTeX There are several elements in LATEX whose colour can be changed to improve th ...
- exchange 2010
Set-MailboxFolderPermission dalian:\Calendar -User Default -AccessRights Reviewer C:\>$rooms = Ge ...
- Chapter 1 -- UsingAndAvoidingNull
"Null sucks." -Doug Lea "Null 很恶心!" "I call it my billion-dollar mistake.&q ...
- IIS 7.0 SSL 部署指南
一. 生成证书请求 1.进入IIS控制台 进入IIS控制台,并选择服务器的服务器证书设置选项. 2.添加证书请求 进入服务器证书配置页面,并选择“创建证书申请” 3.选择加密服务提供 ...
- verilog语法实例学习(2)
Verilog中的信号类型 线网类型 线网类型表示一个或多个门或者其它类型的信号源驱动的硬件连线.如果没有驱动源,则线网的默认值为z.verilog中定义的线网类型有以下几种: wire,tr ...
- Kyoto Cabinet 使用及原理
Kyoto Cabinet 基本规格书 如果你知道 Tokyo Cabinet ,那么就应该知道 Kyoto Cabinet,因为他们都是同一个作者(平林幹雄)开发出来的 Key-Value 数据库. ...