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例子的更多相关文章

  1. 一个简单的CORBA例子

    因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...

  2. 菜鸟学习Hibernate——简单的一个例子

    一.Hibernate开发. 上篇博客已经为大家介绍了持久层框架的发展流程,持久层框架的种类. 为了能够使用Hibernate快速上手,我们先讲解一个简单的Hibernate应用实例hibernate ...

  3. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子

    这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下   我们先来实现一个简单的例子,hello world ...

  4. 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)

    使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...

  5. 使用Multiplayer Networking做一个简单的多人游戏例子-2/3(Unity3D开发之二十六)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51007512 ...

  6. 使用Multiplayer Networking做一个简单的多人游戏例子-1/3(Unity3D开发之二十五)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51006463 ...

  7. 一个简单的cmake例子

    一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库   #在当前目录新建一个build目录,然后cd build ...

  8. vue双向数据绑定最最最最最简单直观的例子

    vue双向数据绑定最最最最最简单直观的例子 一.总结 一句话总结:双向绑定既不仅model可以影响view的数据,view也可以影响model的数据 view model 数据 1.vue双向数据绑定 ...

  9. 一个最简单的JStorm例子

    最简单的JStorm例子分为以下几个步骤: 1.生成Topology Map conf = new HashMp(); //topology所有自定义的配置均放入这个Map TopologyBuild ...

随机推荐

  1. 《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了

    如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...

  2. 为python安装matplotlib模块

    matplotlib是python中强大的画图模块. 首先确保已经安装python,然后用pip来安装matplotlib模块. 进入到cmd窗口下,执行python -m pip install - ...

  3. 《ASP.NET Web API 2框架揭秘》

    <ASP.NET Web API 2框架揭秘> 基本信息 作者: 蒋金楠 出版社:电子工业出版社 ISBN:9787121235368 上架时间:2014-7-5 出版日期:2014 年7 ...

  4. 《C#本质论(第4版)》

    <C#本质论(第4版)> 基本信息 作者: (美)Mark Michaelis    Eric Lippert 译者: 周靖 出版社:人民邮电出版社 ISBN:9787115336750 ...

  5. [Web前端] 给li设置float浮动属性之后,无法撑开外层ul的问题。

    cp from : https://www.cnblogs.com/cielzhao/p/5781462.html 最近在项目中有好几次遇到这个问题,感觉是浮动引起的,虽然用<div style ...

  6. CSS3 Flex布局整理(一)

    一.说明 1.在以往的布局方案中,都是基于盒装模型,依赖display属性+position属性+float属性等. 他对于那些特殊布局非常不方便,比如,垂直居中等. 并且不同浏览器的盒模型还有些差异 ...

  7. tcp常见状态

    常见状态 1.建立连接 2.关闭连接

  8. 在linux下 用p7zip 命令行下 解压 iso文件

    todo tomorrorw! 在linux下可以通过 mount IOSFILE.iso /media/myiso/ -o loop 这种方式挂载,然后直接从 目录中拷贝 iso的内容出来就可以. ...

  9. Java学习笔记——IO操作之以图片地址下载图片

    以图片地址下载图片 读取给定图片文件的内容,用FileInputStream public static byte[] mReaderPicture(String filePath) { byte[] ...

  10. [2014亚马逊amazon] 在线笔试题 大于非负整数N的第一个回文数 Symmetric Number

    1.题目 如标题,求大于整数N(N>=0)的第一个回文数的字符串表示形式. 这个题目也是当时笔试第一次见到,花了一个小时才做出了.慢慢总结还是挺简单的. 2.分析 分析如下: (1)一位数N(9 ...