zoukankan      html  css  js  c++  java
  • webRTc实现视频直播

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

      

  • 相关阅读:
    网络爬虫的基本原理(一)
    灵光一闪-软件应用
    sql语句变量定义和样例
    windows+linux环境部署搭建
    jdk1.6安装
    系统部署
    tomcat部署
    maven各种插件在总结
    maven项目tomcat部署问题
    两种数据源
  • 原文地址:https://www.cnblogs.com/gfweb/p/11252001.html
Copyright © 2011-2022 走看看