import RecordRTC from 'recordrtc';
// getDisplayMedia 提示用户去选择和授权捕获展示的内容或部分内容（如一个窗口）
// getUserMedia 会提示用户给予使用媒体输入的许可，媒体输入会产生一个MediaStream，里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道（来自硬件或者虚拟视频源，比如相机、视频采集设备和屏幕共享服务等等）、一个音频轨道（同样来自硬件或虚拟音频源，比如麦克风、A/D转换器等等），也可能是其它轨道类型。

const _videoFormat = 'mp4';
const _videoType = `video/${_videoFormat}`;

// 录制相关 Stream 流
window.recordStream = {
  desktopStream: null, // 屏幕画面&系统声音 由 getDisplayMedia 提供
  voiceStream: null, // 当前主播麦克风声音 由 getUserMedia 提供
  localStream: null, // trtc 初始化本地音视频流对象
  trtcStream: [], // TRTC 音轨道
};

// 录制 RecordRTC 对象
window.recordVideo = null;

// 保存录制时的 blob 对象
const binaryData = [];

// 检查用户浏览器录制情况
const hasGetUserMedia = !!(navigator.getUserMedia || navigator.getDisplayMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

// 初始化录制器
export function initRecordRTC(){
  if(!hasGetUserMedia) {
    alert("Your browser cannot stream from your webcam. Please switch to Chrome or Firefox.");
    return;
  }
  window.recordVideo = null;
  window.recordStream = {
    desktopStream: null, // 屏幕画面&系统声音 由 getDisplayMedia 提供
    voiceStream: null, // 当前主播麦克风声音 由 getUserMedia 提供
    localStream: null, // trtc 初始化本地音视频流对象
    trtcStream: [], // TRTC 音轨道
  };
  requestUserMedia();
}

// 开始录制
export function startRecord(success = null, error = null){
  console.log('window.recordVideo', window.recordVideo);
  captureDisplayMedia((stream) =>{
    console.log('captureDisplayMedia', stream);
    window.recordStream.desktopStream = new MediaStream(stream);
    // 添加主播麦克风音轨道
    let mainTrack = null
    if (window.recordStream.voiceStream) {
      console.log('window.recordStream.voiceStream.getAudioTracks()', window.recordStream.voiceStream.getAudioTracks());
      mainTrack = window.recordStream.voiceStream.getAudioTracks()[0];
    } else if (window.recordStream.localStream){
      console.log('window.recordStream.localStream.getAudioTrack()', window.recordStream.localStream.getAudioTrack());
      mainTrack = window.recordStream.localStream.getAudioTrack();
    }
    if (mainTrack) {
      window.recordStream.desktopStream.addTrack(mainTrack);
    }

    // 初始化 RecordRTC
    window.recordVideo = RecordRTC(window.recordStream.desktopStream, {
      type: 'video'
    })
    // 初始化 binaryData
    binaryData.splice(-1, binaryData.length);
    binaryData.push(stream);

    // 开始录制
    window.recordVideo.startRecording();

    // 录制视频渲染
    document.querySelector('video#record_rtc_video').srcObject = stream;
    let url = (URL || webkitURL).createObjectURL(new Blob(binaryData, { type: _videoType }));
    document.querySelector('video#record_rtc_video').src = url;
    success && success('ok')
  }, (err)=>{
    console.error('captureDisplayMedia', err);
    error && error(err)
  })
}

// 停止录制
export function stopRecord(){
  console.log('window.recordVideo', window.recordVideo);
  // 停止录制
  window.recordVideo && window.recordVideo.stopRecording(()=>{
    // 初始化视频渲染
    document.querySelector('video#record_rtc_video').srcObject = null;
    document.querySelector('video#record_rtc_video').src = null;

    // 初始化 binaryData
    binaryData.splice(-1, binaryData.length);
    binaryData.push(window.recordVideo.blob);
    let url = (URL || webkitURL).createObjectURL(new Blob(binaryData, { type: _videoType }));
    document.querySelector('video#record_rtc_video').src = url;
  })
}

// 检测是否存在异常
export function hasError(){
  return !window.recordVideo ? true : false;
}

// 下载录制视频
export function downloadRecord(){
  console.log('window.recordVideo', window.recordVideo);
  // 初始化 binaryData
  binaryData.splice(-1, binaryData.length);
  binaryData.push(window.recordVideo.blob);
  let url = (URL || webkitURL).createObjectURL(new Blob(binaryData, { type: _videoType }));
  let fileName =  new Date().getTime() + "." + _videoFormat;
  const aLink = document.createElement('a');
  document.body.appendChild(aLink);
  aLink.style.display='none';
  aLink.href = url;
  aLink.download = fileName;
  aLink.click();
  document.body.removeChild(aLink);
  window.URL.revokeObjectURL(url);
}

// 播放录制视频
export function playRecord(){
  console.log('window.recordVideo', window.recordVideo);
  var recVideo = document.querySelector('video#record_rtc_video');
  // 初始化 binaryData
  binaryData.splice(-1, binaryData.length);
  binaryData.push(window.recordVideo.blob);
  let url = (URL || webkitURL).createObjectURL(new Blob(binaryData, { type: _videoType }));
  recVideo.src = url;
  recVideo.srcObject = null;
  recVideo.controls = true;
  recVideo.volume = 1;
  recVideo.play();
}

// 当录制过程，有音频插入时
export function recordAudioInsert(trtcStream){

  // trtcStream 记录音轨道
  window.recordStream.trtcStream.push(trtcStream);
  // 停止录制
  window.recordVideo && window.recordVideo.stopRecording(()=>{

    // binaryData 追加录制视频
    binaryData.push(window.recordVideo.blob);

    // 整合 stream 流
    const stream = mixerTRTC(window.recordStream.desktopStream, trtcStream);

    // 初始化 RecordRTC
    window.recordVideo = null;
    window.recordVideo = RecordRTC(stream, {
      type: 'video'
    })

    // 开始录制
    window.recordVideo.startRecording();
  })
}

// 混音 TRTC
function mixerTRTC(stream1, stream2){
  const ctx = new AudioContext();
  const dest = ctx.createMediaStreamDestination();

  if( stream1 && stream1.getAudioTracks().length > 0)
      ctx.createMediaStreamSource(stream1).connect(dest);

  if( stream2 && stream2.getAudioTrack())
      ctx.createMediaStreamSource(stream2).connect(dest);

  let tracks = dest.stream && dest.stream.getTracks();
  tracks = tracks.concat(stream1.getVideoTracks()).concat([stream2.getAudioTrack()]);

  return new MediaStream(tracks)
}

// 混音
function mixer(stream1, stream2) {
  const ctx = new AudioContext();
  const dest = ctx.createMediaStreamDestination();

  if(stream1.getAudioTracks().length > 0)
      ctx.createMediaStreamSource(stream1).connect(dest);

  if(stream2.getAudioTracks().length > 0)
      ctx.createMediaStreamSource(stream2).connect(dest);

  let tracks = dest.stream.getTracks();
  tracks = tracks.concat(stream1.getVideoTracks()).concat(stream2.getVideoTracks());

  return new MediaStream(tracks)
}

// 捕捉屏幕媒体
function captureDisplayMedia(callback, error){
  var params = {video: true, audio: true};
  if( navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
    navigator.mediaDevices.getDisplayMedia(params).then(callback).catch((err) => {
      console.error(err.name + ": " + err.message);
      if (err.name == 'NotFoundError' || err.name == 'NotAllowedError') {
        // alert("用户拒绝了使用权限");
      }
      error && error(err)
    });
  } else {
    navigator.getDisplayMedia(params).then(callback).catch((err) => {
      console.error(err.name + ": " + err.message);
      error && error(err)
    });
  }
}

// 请求用户媒体
function requestUserMedia(){
  getUserMedia((stream) => {
    window.recordStream.voiceStream = stream;
    console.log('checkUserMedia', stream)
    // document.getElementById("record_rtc_audio").srcObject = stream;
  }, (err) => {
    console.error("getUserMedia", err.name + ": " + err.message);
  });
}

// 获取用户媒体
function getUserMedia(callback, error){
  var params = { audio: true };
  navigator.getUserMedia = (
    navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia ||
    navigator.msGetUserMedia
  );
  if( typeof navigator.mediaDevices.getUserMedia === 'undefined') {
    navigator.getUserMedia(params).then(callback).catch((err) => {
      console.error("getUserMedia", err.name + ": " + err.message);
      error && error(err)
    });
  } else {
    navigator.mediaDevices.getUserMedia(params).then(callback).catch((err) => {
      console.error("getUserMedia", err.name + ": " + err.message);
      if (err.name == "NotFoundError" || err.name == "DevicesNotFoundError") {
          //required track is missing
          alert("没有找到合适的媒体");
          console.error("没有找到合适的媒体");
      } else if (err.name == "NotReadableError" || err.name == "TrackStartError") {
          //webcam or mic are already in use
          alert("网络摄像头或麦克风已经投入使用")
          console.error("网络摄像头或麦克风已经投入使用")
      } else if (err.name == "OverconstrainedError" || err.name == "ConstraintNotSatisfiedError") {
          //constraints can not be satisfied by avb. devices
      } else if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
          //permission denied in browser
          alert("浏览器拒绝权限");
          console.error("浏览器拒绝权限")
      } else if (err.name == "TypeError" || err.name == "TypeError") {
          //empty constraints object
      } else {
          //other errors
      }
      error && error(err)
    });
  }
}
