<template>
  <div :class="sizeClass" >
    <div class="mic" @mousedown="mouseDownHandle" @mouseup="mouseUpHandle" :title="isRecording?'录音中...':'开始录音'">
      <i :class="`el-icon-${isRecording?'microphone':'turn-off-microphone'}`"></i>
    </div>
  </div>
</template>

<script>
import handle from "@/until/handle";
import {sleep} from "@/until/time";
import ZLMRTCClient from "@/assets/ZLMRTCClient";
import CryptoJS from "crypto-js"

export default {
  name: "microphone.vue",
  props:{
    size: {default:"medium"},
    deviceId: {required:true},
    channelId: {required:true},
    httpsHook: {default:""},
    httpHook: {default:""},
    pushKey: {default:""},
    enableDebug: {default: false}
  },
  data(){
    return {
      iconStyle: "",
      // 音频流
      audioStream: null,
      // record
      mediaRecord: null,
      isRecording: false,
      player: null,
      mediaStream: null,
      audioConnected: false,
    }
  },
  computed: {
    sizeClass() {
      return {
        'microPhone':true,
        'large': this.size === 'large', 'medium': this.size === 'medium', 'small': this.size === 'small'}
    }
  },
  beforeMount() {
    this.initAudioApplications();
  },
  beforeDestroy() {
    if(this.player){
      this.player.close();
      this.player = null;
      this.mediaStream = null;
    }
  },
  methods: {
    /**
     * 初始化app应用
     */
    initAudioApplications(){
      this.player = null;
      this.mediaStream = null;
      this.audioConnected = false;
    },
    // 录音按钮按下
    mouseDownHandle() {
      if (this.audioConnected) {
        // 取消静音音频轨道
        if(this.mediaStream){
          let audioStream = this.mediaStream.getAudioTracks();
          audioStream.forEach(track=>{
            track.enabled = false;
          });
        }else{
          this.$message.error("无法获取音频流!");
        }
      }else{
        // 未创建webrtc 连接
        this.startRecordAudio();
      }
    },
    // 录音按钮抬起
    mouseUpHandle() {
      this.isRecording = false;
      // 静音音频轨道
      if (this.audioConnected && this.mediaStream) {
        let audioStream = this.mediaStream.getAudioTracks();
        audioStream.forEach(track => {
          track.enabled = false;
        });
      }
    },

    async startRecordAudio() {
      let err, stream, res;
      if (!this.mediaStream) {
        let httpsHook = this.httpsHook;
        let pushKey = this.pushKey;
        pushKey = CryptoJS.MD5(pushKey);
        let serverHost = `${httpsHook}`
        let app = "rtc";
        let stream = `audio${this.deviceId}`
        // webrtc 请求推流 url
        let zlmSdpUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=push&sign=${pushKey}`;
        // webrtc 拉流地址
        let playAudioStreamUrl = `${serverHost}/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
        console.log(playAudioStreamUrl);

        let player = new ZLMRTCClient.Endpoint(
          {
            // element: document.getElementById('video'),// video 标签
            debug: true,// 是否打印日志
            zlmsdpUrl: zlmSdpUrl,//流地址
            simulcast: false,
            useCamera: false,
            audioEnable: true,
            videoEnable: false,
            recvOnly: false,
            resolution: {w: 0, h: 0},
            usedatachannel: false,
          }
        );
        this.player = player;
        // console.log(player);
        player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, async (state) => {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
          console.log('当前状态==>', state);
          if (state === 'connected') {
            // 等待1秒
            await sleep(1000);
            [err, res] = await handle(this.sendBroaderCast(stream));
            if (err) {
              this.audioStartFailed(err,`与设备交互错误信息失败${err.message}`)
              this.mediaStream = null;
              return player.close();
            }
            this.audioConnected = true;
            console.log('创建音视频通道成功');
          } else if(state === 'close'){
            this.$message.warning("webrtc连接断开");
            this.audioConnected = false;
          }
        });
        player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,  (e)=> {
          this.audioStartFailed(e,"ICE 协商出错");
        });
        // player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS, function (e) {//获取到了远端流，可以播放
        //   console.log('播放成功', e.streams)
        // });
        player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,  (e)=> {
          this.audioStartFailed(e,"offer anwser 交换失败");
        });
        player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,  (s)=> {
          console.log("获取到了本地流");
          this.mediaStream = s;
        });
        player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,  (s)=> {
          this.audioStartFailed(s,"获取音频信息失败,请检查是否有麦克风");
        });
      }
      this.isRecording = true;
    },
    async stopRecordAudio() {
      //  todo 停止录音
    },
    audioStartFailed(e,msg){
      if(this.enableDebug){
        console.log(msg);
        console.log(e);
        console.log("-------");
      }
      this.$message.error(msg);
    },
    // 通知设备开启推流
    sendBroaderCast(stream) {
      let url = `/api/play/broadcast`
      url += `?deviceId=${this.deviceId}&stream=${stream}`;
      return this.$axios({
        method: 'get',
        url: url
      });
    }
  }

}
</script>

<style scoped>
.microPhone{
  display: flex;
  justify-content: center;
  align-items: center;
}
.microPhone .mic{
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.small{width: 25px;height:25px;font-size: 1.8rem;}
.medium{width: 40px;height:40px;font-size: 2.2rem;}
.large{width: 60px;height:60px;font-size: 2.6rem;}
.huge{width: 80px;height:80px;font-size: 2.8rem;}
</style>
