<template>
  <div>
    <a-space direction="vertical" style="width: 100%">
      <a-row :gutter="16">
        <a-col :span="12">
          <a-card>
            <template #title>本地视频</template>
            <video id="localVideo" autoplay="autoplay" style="width: 100%" />
          </a-card>
        </a-col>
        <a-col :span="12">
          <a-card>
            <template #title>远程视频</template>
            <video id="remoteVideo" autoplay="autoplay" style="width: 100%" />
          </a-card>
        </a-col>
      </a-row>

      <a-alert
        v-if="noticeMessage"
        :message="noticeMessage"
        type="info"
        show-icon
      />
    </a-space>
  </div>
</template>

<script>

import Common from '../common/Common.js';

export default {

  props: {
    'caller' : {
      type: String,
      default: null,
    },
    'connectionId' : {
      type: String,
      default: null,
    },
  },



  data: function(){
    return {
      noticeMessage: '',  // 通知消息
      loginInfoJsonStr: '',       // 用户登录信息
      uid: '',
    };
  },

  mounted: function() {
    var _self = this;

    navigator.getUserMedia = navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.msGetUserMedia;
        
        
    //兼容浏览器的PeerConnection写法
    window.PeerConnection = (window.PeerConnection ||
            window.RTCPeerConnection ||
            window.webkitPeerConnection00 || 
            window.webkitRTCPeerConnection || 
            window.mozRTCPeerConnection);

    _self.loginInfoJsonStr = localStorage.getItem('#LoginInfo');

    _self.localVideo = document.getElementById('localVideo');
    _self.remoteVideo = document.getElementById('remoteVideo');

    _self.localStream = null;
  },

  methods: {

    // 打开websocket
    openWebSocket: function() {
      var _self = this;

      var websocketUrl = Common.getApiURL('WebSocket/ChatVideo/' + _self.uid);

      if(websocketUrl.indexOf('https') == 0){
        websocketUrl = websocketUrl.replace('https','wss').replace('/api','');
      }else if(websocketUrl.indexOf('http') == 0){
        websocketUrl = websocketUrl.replace('http','ws').replace('/api','');
      }
            
      _self.webSocket = new WebSocket(websocketUrl);

      _self.webSocket.onopen = function() {
        console.log('websocket打开');

        // 打开 RTC Peer Connection
        _self.openPeerConnection();
        // 向PeerConnection中加入需要发送的流
        _self.peerConnection.addStream(_self.localStream);

                
        if(_self.caller == true){
          _self.websocketSendTextMessage('RegisterConnection ' + _self.loginInfoJsonStr);
        }else{
          _self.websocketSendTextMessage('BuildConnection ' + _self.connectionId);
        }
      };

      _self.webSocket.onmessage = function(message) {
        console.log('websocket 收到信息 : ' + message.data);

        var msg = JSON.parse(message.data);

        if(msg.type === '__ice_candidate' ){
          //如果是一个ICE的候选，则将其加入到PeerConnection中
          _self.peerConnection.addIceCandidate(new RTCIceCandidate(msg.data.candidate));
        } else if (msg.type === '__offer') {
          // 否则设定对方的session描述为传递过来的描述
          _self.peerConnection.setRemoteDescription(new RTCSessionDescription(msg.data.sdp));

          // 如果是接受方则方一个answer信令
          _self.peerConnection.createAnswer(sessionDescription => {
            _self.peerConnection.setLocalDescription(sessionDescription);
            _self.webSocketSendJsonMessage({
              'type': '__answer',
              'data': {
                'sdp': sessionDescription,
              },
            });
          }, error => {
            // PeerConnection创建offer失败
            console.log('Peer Connection创建answer失败');
            console.log(error);
          });
        } else if (msg.type === '__answer') {
          // 否则设定对方的session描述为传递过来的描述
          _self.peerConnection.setRemoteDescription(new RTCSessionDescription(msg.data.sdp));
        } else if (msg.type === 'nowaiting') {
          console.log('等待对方加入。');
          _self.noticeMessage = '等待对方加入！';                   
        } else if(msg.type === 'Connected'){
          // websocket 已经建立了连接
          console.log('已经有人接听了。');
                    
          if (_self.caller) {
            // 如果是发起方则发送一个offer信令
            _self.peerConnection.createOffer(sessionDescription => {
              _self.peerConnection.setLocalDescription(sessionDescription);
              _self.webSocketSendJsonMessage({ 
                'type': '__offer',
                'data': {
                  'sdp': sessionDescription,
                },
              });
            }, error => {
              // PeerConnection创建offer失败
              console.log('Peer Connection创建offer失败');
              console.log(error);
            });
          }
        } else if (msg.type === 'bye') {
          _self.close();
        } 
      };

      _self.webSocket.onclose = function() {
        console.log('websocket关闭');
        _self.webSocket = null;
      };

      _self.webSocket.onerror = function(event) {
        console.log('websocket异常');
        console.log(event);
        _self.webSocket.close();
      };
    },

    /**
         * WebSocket发送Json信息
         */
    webSocketSendJsonMessage: function(jsonData) {
      var _self = this;

      var jsonText = JSON.stringify(jsonData);

      if (_self.webSocket != null) {
        _self.webSocket.send(jsonText);
        console.log('websocket发送信息 : ' + jsonText);
      }else{
        console.log('websocket未打开，不能发送消息：' + jsonText);
      }
    },


    /**
         * WebSocket发送文字消息
         */
    websocketSendTextMessage: function(text){
      var _self = this;

      if (_self.webSocket != null) {
        _self.webSocket.send(text);
        console.log('websocket发送信息 : ' + text);
      }else{
        console.log('websocket未打开，不能发送消息' + text);
      }
    },



    // 打开连接
    openPeerConnection: function() {
      var _self = this;

      var server = { iceServers: [{ url: 'stun:stun.l.google.com:19302' }] };

      // 参数为null则没有iceserver，即使没有stunserver和turnserver，仍可在局域网下通讯
      // eslint-disable-next-line
      _self.peerConnection = new PeerConnection(null);

      _self.peerConnection.onconnecting = function(message) {
        console.log('RTC Peer Connection连接中');
      };

      _self.peerConnection.onopen = function(message) {
        console.log('RTC Peer Connection连接已打开');                
      };

      // 发送ICE候选到其他客户端
      _self.peerConnection.onicecandidate = function(event) {
        if (event.candidate) {
          _self.webSocketSendJsonMessage({
            'type': '__ice_candidate',
            'data': {
              'candidate': event.candidate,
            },
          });                    
        }
      };

      // 如果检测到媒体流连接到本地，将其绑定到一个video标签上输出
      _self.peerConnection.onaddstream = function(event) {
        console.log('远程视频添加');
        _self.remoteVideo.srcObject = event.stream;                
        _self.noticeMessage = null;
        _self.waitForRemoteVideo();
      };

      _self.peerConnection.onremovestream = function(event) {
        console.log('远程视频移除');
      };
    },

        
    // 等待远程视频
    waitForRemoteVideo: function() {
      var _self = this;
      if (_self.remoteVideo.currentTime > 0) {
        // 判断远程视频长度
        console.log('接收到远程视频。');
        return;
      } else {
        console.log('等待远程视频。');
        setTimeout(_self.waitForRemoteVideo, 1000);
      }
    },

    /**
         * 打开本机的媒体
         */
    openUserMedia: function() {
      var _self = this;
      console.log('获取用户媒体');

      navigator.getUserMedia(
        {
          audio: true,
          video: true,
        },
        stream => {
          console.log('获取用户媒体成功。');
          // 绑定本地媒体流到video标签用于输出
          _self.localVideo.srcObject = stream;

          _self.localStream = stream;

          _self.openWebSocket();
        },
        error => {
          console.log('获取用户流失败！');
          console.log(error);
          _self.noticeMessage = '获取用户流失败！';
        },
      );
    },

    /**
         * 获取UUID
         */
    guid: function () {
      // 生成任意数
      function S4(){
        return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
      }
      return (S4() + '-' 
                + S4() + '-' 
                + S4() + '-' 
                + S4() + '-' 
                + S4() + '-' 
                + S4() + '-' 
                + S4() + '-' 
                + S4());
    },

    /**
         * 初始化
         */
    open: function() {
      this.close();
      console.log('初始化');
      this.uid = this.guid();  
      this.openUserMedia();      
    },

    close: function(){
      var _self = this;

      if(_self.webSocket){
        _self.webSocketSendJsonMessage({ type: 'bye' });
        _self.webSocket.close();
      }

      if(_self.peerConnection){
        _self.peerConnection.close();
      }

      // 关闭所有的video
      var videos = document.getElementsByTagName('video');
      for (let i = 0; i < videos.length; i++) {
        videos[i].pause();
      }
      // 关闭本地视频
      if(_self.localVideo.srcObject){
        let tracks = _self.localVideo.srcObject.getTracks();
        if(tracks){
          for(let i = 0; i < tracks.length; i ++){
            tracks[i].stop(); //关闭摄像头
          }
        }             
      }
      _self.localVideo.srcObject = null;

      // 关闭远程视频
      if(_self.remoteVideo.srcObject){
        let tracks = _self.remoteVideo.srcObject.getTracks();
        if(tracks){
          for(var i = 0; i < tracks.length; i ++){
            tracks[i].stop(); //关闭摄像头
          }
        }
      }
      _self.remoteVideo.srcObject = null;

      _self.noticeMessage = '对方已断开！';
            
      _self.localStream = null;
    },
  },

  destoryed: function() {
    this.close();
  },
};
</script>

<style scoped>
    .m-video{
        width: 100%;
    }
</style>
