<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='https://cdn.scaledrone.com/scaledrone.min.js'></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
body {
display: flex;
height: 100vh;
margin: 0;
align-items: center;
justify-content: center;
padding: 0 50px;
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
video {
max-width: calc(50% - 100px);
margin: 0 50px;
box-sizing: border-box;
border-radius: 2px;
padding: 0;
box-shadow: rgba(156, 172, 172, 0.2) 0px 2px 2px, rgba(156, 172, 172, 0.2) 0px 4px 4px, rgba(156, 172, 172, 0.2) 0px 8px 8px, rgba(156, 172, 172, 0.2) 0px 16px 16px, rgba(156, 172, 172, 0.2) 0px 32px 32px, rgba(156, 172, 172, 0.2) 0px 64px 64px;
}
.copy {
position: fixed;
top: 10px;
left: 50%;
transform: translateX(-50%);
font-size: 16px;
color: rgba(0, 0, 0, 0.5);
}
</style>
</head>
<body>
<div class="copy">Send your URL to a friend to start a video call</div>
<video id="localVideo" autoplay muted></video>
<video id="remoteVideo" autoplay></video>
<script src="script.js"></script>
</body>
</html> <script>
// 如果需要,生成随机的房间名称
if (!location.hash) {
location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
const roomHash = location.hash.substring(1); console.log(roomHash)
// 用您自己的通道ID替换
const drone = new ScaleDrone('yiS12Ts5RdNhebyM');
//房间名称前须加上“可观察到的-”
const roomName = 'observable-' + roomHash;
const configuration = {
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}]
};
let room;
let pc; function onSuccess() {};
function onError(error) {
console.error(error);
}; drone.on('open', error => {
if (error) {
return console.error(error);
}
room = drone.subscribe(roomName);
room.on('open', error => {
if (error) {
onError(error);
}
});
// 我们连接到房间并接收到一组“成员”
// 连接到房间(包括我们)。信令服务器准备好了。
room.on('members', members => {
console.log('MEMBERS', members);
// 如果我们是第二个连接到房间的用户,我们将创建offer
const isOfferer = members.length === 2;
startWebRTC(isOfferer);
});
}); // 通过Scaledrone发送信号数据
function sendMessage(message) {
drone.publish({
room: roomName,
message
});
} function startWebRTC(isOfferer) {
pc = new RTCPeerConnection(configuration); // “onicecandidate”在ICE代理需要交付a时通知我们
// 通过信令服务器向另一个对等点发送消息
pc.onicecandidate = event => {
if (event.candidate) {
sendMessage({'candidate': event.candidate});
}
}; // If user is offerer let the 'negotiationneeded' event create the offer
if (isOfferer) {
pc.onnegotiationneeded = () => {
pc.createOffer().then(localDescCreated).catch(onError);
}
} // 当远程流到达时,将其显示在#remoteVideo元素中
pc.ontrack = event => {
const stream = event.streams[0];
if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {
remoteVideo.srcObject = stream;
}
}; navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
}).then(stream => {
// 在#localVideo元素中显示本地视频
localVideo.srcObject = stream;
// 添加要发送到conneting对等点的流
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}, onError); // 听Scaledrone的信号数据
room.on('data', (message, client) => {
// 消息是由我们发出的
if (client.id === drone.clientId) {
return;
} if (message.sdp) {
// 这是在收到来自其他同事的提议或回答后调用的
pc.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
// 当收到offer时,让我们答复
if (pc.remoteDescription.type === 'offer') {
pc.createAnswer().then(localDescCreated).catch(onError);
}
}, onError);
} else if (message.candidate) {
// 将新的ICE候选项添加到我们的连接远程描述中
pc.addIceCandidate(
new RTCIceCandidate(message.candidate), onSuccess, onError
);
}
});
} function localDescCreated(desc) {
pc.setLocalDescription(
desc,
() => sendMessage({'sdp': pc.localDescription}),
onError
);
} </script>

免费的stun服务器:

stun:stun1.l.google.com:19302
stun:stun2.l.google.com:19302
stun:stun3.l.google.com:19302
stun:stun4.l.google.com:19302
stun:23.21.150.121
stun:stun01.sipphone.com
stun:stun.ekiga.net
stun:stun.fwdnet.net
stun:stun.ideasip.com
stun:stun.iptel.org
stun:stun.rixtelecom.se
stun:stun.schlund.de
stun:stunserver.org
stun:stun.softjoys.com
stun:stun.voiparound.com
stun:stun.voipbuster.com
stun:stun.voipstunt.com
stun:stun.voxgratia.org
stun:stun.xten.com

线上视频必须配置https或者本地localhost  才能实现视频通信

windows配置https

	server {
# HTTPS 默认443端口
listen 443 ssl;
server_name localhost;
# 证书文件配置,指定证书的路径,除了证书路径其他配置都默认
ssl_certificate D:/Dev/https-sll/1_www.deceen.com_bundle.crt;
ssl_certificate_key D:/Dev/https-sll/2_www.deceen.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5:!DH; #设置长连接
keepalive_timeout 70;
#减少点击劫持
add_header X-Frame-Options DENY;
#禁止服务器自动解析资源类型
add_header X-Content-Type-Options nosniff;
#防XSS攻击
add_header X-Xss-Protection 1; # 代码的根目录
root html;
# 默认index
index /video/webrtc/index.html; # 访问日志
#access_log /home/wwwlogs/example.com.log main; # 文件的规则(详见http://seanlook.com/2015/05/17/nginx-location-rewrite/index.html)
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
}
location ~ .*\.(js|css)?$ {
expires 12h;
}
}

  

webRTc实现视频直播的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(六六)-- 三个角度分析美女视频直播这个行业

    本文主要从用户,公司和技术角度分析美女视频直播这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help 美女视频直播 ...

  2. Android IOS WebRTC 音视频开发总结(五八)-- 图文解说视频直播原理

    本文主要介绍rtmp&hls视频直播原理,文章最早发表在我们的微信公众号上,详见这里,欢迎关注微信公众号blackerteam,更多详见www.blackerteam.com 现在视频直播很火 ...

  3. Vue + WebRTC 实现音视频直播(附自定义播放器样式)

    1. 什么是WebRTC 1.1 WebRTC简介 WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频 ...

  4. 10┃音视频直播系统之 WebRTC 中的数据统计和绘制统计图形

    一.数据统计 在视频直播中,还有一项比较重要,那就是数据监控 比如开发人员需要知道收了多少包.发了多少包.丢了多少包,以及每路流的流量是多少,才能评估出目前用户使用的音视频产品的服务质量是好还是坏 如 ...

  5. 12┃音视频直播系统之 WebRTC 实现1对1直播系统实战

    一.搭建 Web 服务器 前面我们已经实现过,但是没有详细说HTTPS服务 首先需要引入了 express 库,它的功能非常强大,用它来实现 Web 服务器非常方便 同时还需要引入 HTTPS 服务, ...

  6. Android IOS WebRTC 音视频开发总结(七六)-- 探讨直播低延迟低流量的粉丝连麦技术

    本文主要探讨基于WebRTC的P2P直播粉丝连麦技术 (作者:郝飞,亲加云CTO,编辑:dora),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注微信公众号blacker(微信ID:blac ...

  7. 【腾讯bugly干货分享】HTML 5 视频直播一站式扫盲

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1277 视频直 ...

  8. 【腾讯Bugly干货分享】H5 视频直播那些事

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57a42ee6503dfcb22007ede8 Dev Club 是一个交流移动 ...

  9. Android IOS WebRTC 音视频开发总结(八十一)-- WebRTC靠谱吗?有没有适合的SDK推荐?

    作者:blaker,最早发表在我们的微信公众和[编风网],详见[这里] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blackerteam 或 webrtcorgcn) ...

随机推荐

  1. Unity WebGL

    路过弄了个unity Unity导出WebGL不支持c#socket和unity的network 可以用javascript的websocket实现... c#一般通过www从phpserver获取. ...

  2. 总结一篇shell调试技巧及常见的脚本错误

      #常见的调试命令工具 1.使用bash命令参数调试 #使用 [root@game ~]# sh [-xvn] test.sh #参数解释: -x:将执行的脚本内容输出出来,可以看到执行的过程 -n ...

  3. C++11中std::move、std::forward、左右值引用、移动构造函数的测试

    关于C++11新特性之std::move.std::forward.左右值引用网上资料已经很多了,我主要针对测试性能做一个测试,梳理一下这些逻辑,首先,左值比较熟悉,右值就是临时变量,意味着使用一次就 ...

  4. 自定义注解-方法重试@RetryProcess

    背景 在项目开发中,有时候会出现接口调用失败,本身调用又是异步的,如果是因为一些网络问题请求超时,总想可以重试几次把任务处理掉. 一些RPC框架,比如dubbo都是有重试机制的,但是并不是每一个项目多 ...

  5. [oracle/sql]关于清除重复,not in方案和not exists方案的对比

    有这样一张表: CREATE TABLE tb_sc ( id NUMBER not null primary key, studentid int not null, courseid int no ...

  6. 关于Vue-CLI的那些事儿

    Vue CLI是基于Vue.js进行快速发展的完整系统,提供了: 交互式的项目脚手架 实现零配件的原型开发 图形化的创建和管理项目的界面 基本框架的构建: . ├── build/ # webpack ...

  7. 自定义AQS独占模式下的同步器来实现独享锁

    自定义AQS独占模式下的同步器来实现独享锁 /** * 自定义AQS独占模式下的同步器来实现独享锁 */ public class Mutex implements Lock, java.io.Ser ...

  8. get、post请求方式在postman中使用步骤

    1.get请求方式:不需要借助任何工具,在浏览器里面就可以发送请求,直接在浏览器里面输入访问      url?参数名=参数值  url?parma=abc&name=abcd 2.post请 ...

  9. oracle之三资源管理

    Oracle 资源管理 12.1 为什么要使用Oracle资源管理器 传统意义上,系统的资源分配是由OS来完成的,但是对于数据库资源,OS分配资源会带来一些问题: 以Linux为例,最为突出的一个问题 ...

  10. oracle之创建和管理数据库用户账户

    创建和管理数据库用户账户 sys 查看数据库里有多少用户?select username from dba_users; 9.1.1用户的缺省表空间 每个用户账户都可以指定默认的表空间,用户创建的任何 ...