需求:视频和音频分开播放,视频可以有可以无,音频至少一个,由于音频和视频有时差,需要依据视频进行校准。
思路:用定时器延迟

video.js的视频插件,在点击时间轴时,会执行如下函数:
当是在播放时,点击时间轴:先执行pause(暂停)→seeking(跳转)→canplaythrough(视频加载完成)/play(播放),当网络不佳时,先执行play,后执行canplaythrough,当网络情况好时,先执行后执行canplaythrough。
当是在暂停时,点击时间轴:先执行seeking→canplaythrough

openVideo() {
    let that = this;
    that.player.reset(); //重置 video
    that.player.src([
      {
        type: "video/mp4",
        src: that.videoUrl,
      },
    ]);
    that.player.load(); // 每次重复打开视频,都将视频进度条置为0
    that.player.play();
    this.videoFlag = true;
    that.player.on("canplaythrough", () => {
      // 视频加载好了,能够不停顿地一直播放时执行函数
      // 在视频时间轴上跳转时,加载成功,回调也会执行
      console.log("canplaythrough", that.player.currentTime());
      that.player.markers.reset(that.markersList); // 视频打点
      that.player.markers.updateTime(); // 视频打点
      that.seeking(false); // 进入页面,即刻播放音频
      that.loadedmetadata = true;
    });
    that.player.on("play", () => {
      // 点击播放按钮时会播放,并且调用play函数时会调用
      console.log("play", that.loadedmetadata);
      if (that.loadedmetadata && !that.isSeeking) {
        // 只在点击播放按钮时会播放
        //点击进度条时,不执行回调
        that.seeking(false);
      }
    });
    that.player.on("pause", () => {
      // 点击暂停按钮时会执行
      that.seeking(true);
    });
    that.player.on("seeking", () => {
      that.isSeeking = true;
      console.log("seeking");
      // that.seeking();
    });
  }
  
  
closeVideo(): void {
    // 点击关闭后,防止play回调函数中的音频执行
    this.loadedmetadata = false;
    this.player.pause(); // 暂停视频时会执行回调去暂停和音频
    this.videoFlag = false;
    clearTimeout(this.timerSeekingOne); // 清除定时器
    clearTimeout(this.timer); // 清除定时器
  }
  // 主要函数
 seeking(isPause?: boolean) {
    // 该函数主要是在跳转进度条时,让音频对应跳转
    clearTimeout(this.timerSeekingOne); // 每一次执行都清除定时器
    let currentTimeVideo = this.player.currentTime();
    let audioDomList = document.getElementsByTagName("audio");
    console.log(this.audioDiffrentTimeArray);
    this.audioDiffrentTimeArray.forEach((audioDiffTimeItem, index) => {
      const isTime = Math.abs(audioDiffTimeItem); // 取绝对值
      if (currentTimeVideo < isTime && audioDiffTimeItem < 0) {
        // 视频先录,并且有差值,音频才延迟播放
        const time1 = new Date().getTime();
        console.log("循环的item", audioDiffTimeItem, index);
        // audioDomList[index]["src"] = null;
        audioDomList[index].pause();

        // 定时器================ 定时器
        if (!isPause) {
          // 在延迟段内暂停,禁止计时播放
          let diff = (isTime - currentTimeVideo) * 1000;
          this.timerSeekingOne = setTimeout(() => {
            // 让音频延迟到指定秒数后再播放
            console.log(
              "定时器=====应该延迟的时间",
              isTime - currentTimeVideo,
              "s",
              "延迟了,音频时间",
              new Date().getTime() - time1,
              "ms"
            );
            // audioDomList[index].src = this.audioList[index].fileName;
            // audioDomList[index].load(); // 重置音频地址,音频置零
            audioDomList[index].currentTime = 0; // 重置音频地址,音频置零
            console.log(
              "音频的起始时间是多少?",
              audioDomList[index]["currentTime"],
              index
            );
            this.playAudio(index); // 播放
          }, diff);
        } else {
          console.log("是暂停", isTime - currentTimeVideo);
        }
      } else {
        // 如果时间差为正,说明音频先录,理想情况是一起录制
        // 如果音频后录制,播放已经超过延迟时间
        // 所以播放音频时,音频播放时间需要后移
        const audioItemStartTime =
          currentTimeVideo + this.audioDiffrentTimeArray[index];
        audioDomList[index]["currentTime"] = audioItemStartTime;
        // audioItemStartTime为负数时,默认取0
        if (isPause) {
          // 不在延迟段内暂停,直接暂停
          this.pauseAudio(index);
        } else {
          this.playAudio(index);
        }
      }
    });
  }
  
 pauseAudio(indexVal?: number) {
    let audioDomList = document.getElementsByTagName("audio");
    console.log(typeof indexVal);
    if (typeof indexVal !== "number") {
      this.audioList.forEach((audioItem, index) => {
        console.log(audioDomList[index].src);
        if (audioDomList[index].src) {
          // 如果音频地址存在,则播放
          audioDomList[index].pause();
        }
      });
    } else {
      audioDomList[indexVal].pause();
    }
  }
playAudio(indexVal?: number) {
    this.timer && clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.isSeeking = false; // 确保是在最后,置空
      // 确保在跳转的时候不执行play回调
    }, 500);
    let audioDomList = document.getElementsByTagName("audio");
    if (typeof indexVal !== "number") {
      // 如果不是通过跳转时间点进入播放
      this.audioList.forEach((audioItem, index) => {
        if (audioItem.fileName) {
          // 如果音频地址存在,则播放
          audioDomList[index].play();
        }
      });
    } else {
      audioDomList[indexVal].play();
    }
  }