<!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;
        }
    }

  

posted on 2019-07-26 17:58  菜鸡H  阅读(3117)  评论(0编辑  收藏  举报