html中使用vue3中setup的dplayer播放器

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>
    Document
  </title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
  </style>
</head>

<body>
  <script src="./script/vue.global.js"></script>
  <script src="./script/DPlayer.min.js"></script>
  <script src="./script/hls.min.js"></script>
  <script src="./script/axios.min.js"></script>
  <div id="app">
    <div style="width: 100vw; height: 100vh">
      <!--    -->
      <!--  -->
      <dplayer v-if="showVideo" :video="dplayerObj.video" ref="dplayerVideo" screenshot :loop="true" :autoplay="false"
        @ended="videoFinish" @play="heartBeatApiFun(1)" @pause="heartBeatApiFun(2)" />
    </div>
  </div>
  <script>
    const timerObj = {
      timer: null,
      sec: 15000,
      // getTime
      setTimer: function (callback) {
        this.timer && this.removeTimer();
        this.timer = setTimeout(() => {
          this.callback && this.callback();
          this.setTimer();
        }, this.sec);
      },
      removeTimer: function () {
        clearTimeout(this.timer);
        this.timer = null;
      },
      callback: () => { },
    };
    function guid() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function (c) {
          var r = (Math.random() * 16) | 0,
            v = c == "x" ? r : (r & 0x3) | 0x8;
          return v.toString(16);
        }
      );
    }
    function suffix(name) {
      //获取图片后缀
      name = name.split("?")[0];
      let fileName = name.lastIndexOf(".");
      let fileNameLength = name.length;
      let fileFormat = name.substring(fileName + 1, fileNameLength);
      return fileFormat;
    }
    var videoBox = null;
    const {
      ref,
      reactive,
      onBeforeUnmount,
      onMounted,
      nextTick,
      defineEmits,
      defineProps,
      defineExpose,
      createApp,
    } = Vue;
  </script>
  <script>
    const videoPlayer = {
      template: `
         <div style="width: 100%; height: 100%" id="videoRef" ref="videoRef"></div>
`,
      emits: ["ended", "play", "pause", "changeMaxTime"],
      props: {
        // 是否自动播放
        autoplay: {
          type: Boolean,
          default: false,
        },
        // 主题色
        theme: {
          type: String,
          default: "#0093ff",
        },
        // 视频是否循环播放
        loop: {
          type: Boolean,
          default: true,
        },
        // 语言(可选值: 'en', 'zh-cn', 'zh-tw')
        lang: {
          type: String,
          default: "zh-cn",
        },
        // 是否开启截图(如果开启,视频和视频封面需要允许跨域)
        screenshot: {
          type: Boolean,
          default: false,
        },
        // 是否开启热键
        hotkey: {
          type: Boolean,
          default: true,
        },
        // 视频是否预加载(可选值: 'none', 'metadata', 'auto')
        preload: {
          type: String,
          default: "auto",
        },
        // 默认音量
        volume: {
          type: Number,
          default: 0.7,
        },
        // 可选的播放速率,可以设置成自定义的数组
        playbackSpeed: {
          type: Array,
          default: [0.5, 0.75, 1, 1.25, 1.5, 2],
        },
        disableSpeed: {
          type: Boolean,
          default: false,
        },
        disableProgress: {
          type: Boolean,
          default: false,
        },
        effMaxStudyTimes: {
          type: Number,
          default: 0,
        },
        // 在左上角展示一个 logo,你可以通过 CSS 调整它的大小和位置
        logo: {
          type: String,
          default: "",
        },
        // 视频信息
        video: {
          type: Object,
          default: {
          },
        },
        // 外挂字幕
        subtitle: {
          type: Object,
          default: {},
        },
        // 显示弹幕
        danmaku: {
          type: Object,
          default: {},
        },
        // 自定义右键菜单
        contextmenu: {
          type: Array,
          default: [],
        },
        // 自定义进度条提示点
        highlight: {
          type: Array,
          default: [],
        },
        // 阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
        mutex: {
          type: Boolean,
          default: true,
        },
      },
      setup(props, context) {
        // const videoRef = ref(null);
        // console.log(props)
        const state = reactive({
          instance: null,
        });
        const fullscreenStatus = ref({
          webfullscreen: false,
          fullscreen: false,
        });

        onMounted(() => {
          var videoRef = document.getElementById("videoRef");
          let player = {
            container: videoRef,
            autoplay: props.autoplay,
            theme: props.theme,
            loop: props.loop,
            lang: props.lang,
            screenshot: props.screenshot,
            hotkey: props.hotkey,
            preload: props.preload,
            volume: props.volume,
            playbackSpeed: props.playbackSpeed,
            video: props.video,
            contextmenu: props.contextmenu,
            highlight: props.highlight,
            mutex: props.mutex,
          };
          if (props.subtitle.url) {
            player.subtitle = props.subtitle;
          }
          console.log(player);
          state.instance = new DPlayer(player);
          videoBox = {
            isCanPlay,
            switchVideo,
            seekkVideo,
            getSeekTime,
            setSeekTime,
            play,
            pause,
            cancelFull,
            backFull,
          };

          state.instance.on("ended", () => {
            if (props.disableProgress) {
              var duration = state.instance.video.duration;
              if (Math.abs(props.effMaxStudyTimes - duration)
                < 5) {
                context.emit("ended");
              }
            } else {
              context.emit("ended");
            }
          });
          state.instance.on("play", () => {
            context.emit("play");
          });

          state.instance.on("pause", () => {
            context.emit("pause");
          });
          state.instance.on("fullscreen", () => {
            // console.log("fullscreen");
            fullscreenStatus.value.fullscreen = true;
          });
          state.instance.on("fullscreen_cancel", () => {
            // console.log("fullscreen_cancel");
            fullscreenStatus.value.fullscreen = false;
          });
          state.instance.on("webfullscreen", () => {
            // console.log("webfullscreen");
            fullscreenStatus.value.webfullscreen = true;
          });
          state.instance.on("webfullscreen_cancel", () => {
            fullscreenStatus.value.webfullscreen = false;
            // console.log("webfullscreen_cancel");
          });
          if (props.disableSpeed) {
            state.instance.container.querySelector(
              ".dplayer-setting-speed"
            ).style.display = "none";
          }
          if (props.disableProgress) {
            var videoTime = 0;
            // console.log(props.effMaxStudyTimes);
            state.instance.on("timeupdate", function (e) {
              var videoCurrentTime = state.instance.video.currentTime;
              if (videoCurrentTime > props.effMaxStudyTimes) {
                if (
                  videoCurrentTime - videoTime >
                  0.8 * state.instance.video.playbackRate
                ) {
                  state.instance.seek(videoTime);
                  state.instance.notice(
                    "最大学习时间为:" + getTime(props.effMaxStudyTimes),
                    2000
                  );
                  state.instance.notice("禁止快进", 2000);
                } else {
                  if (videoCurrentTime > props.effMaxStudyTimes > 0) {
                    context.emit("changeMaxTime", videoCurrentTime);
                  }
                  videoTime = videoCurrentTime;
                }
              } else {
                videoTime = videoCurrentTime;
              }
              // videoTime = videoCurrentTime;
            });
            state.instance.on("notice_show", function (e) {
              if (videoTime > props.effMaxStudyTimes) {
                var text = e.innerText;
                //
                if (
                  "禁止快进" != text &&
                  (text.indexOf("快进") > -1 || text.indexOf("快退") > -1)
                ) {
                  e.style.display = "none";
                }
              }
            });
          }
        });
        // 销毁
        onBeforeUnmount(() => {
          state.instance.destroy();
        });
        function switchVideo(item) {
          //    state.instance.pause()
          console.log(item);
          state.instance.switchVideo(item);
        }
        function seekkVideo(time) {
          state.instance.seek(time);
        }
        function getSeekTime() {
          return state.instance.video.currentTime;
        }
        function play() {
          // state.instance.play()
          state.instance.video
            .play()
            .then((e) => {
              console.log(e);
            })
            .catch((e) => {
              console.log(e);
            });
        }
        function pause() {
          state.instance.pause();
        }
        var isCanPlayFun;
        function isCanPlay(callback) {
          // state.instance.off('canplay',isCanPlayFun)
          // state.instance.on('canplay',isCanPlayFun)
          isCanPlayFun = () => {
            console.log(12121212);
            callback();
          };
          // state.instance.video.removeEventListener('canplay',isCanPlayFun,false)
          state.instance.video.addEventListener("canplay", isCanPlayFun, {
            once: true,
          });
        }
        function setSeekTime(time, desc) {
          if (time) {
            state.instance.notice("上次记录:" + getTime(time), 2000);
          }
          return (state.instance.video.currentTime = time);
        }
        const fullscreenTempStatus = ref({});
        function cancelFull() {
          fullscreenTempStatus.value = { ...fullscreenStatus.value };
          if (fullscreenStatus.value.fullscreen) {
            state.instance.fullScreen.cancel("browser");
          }
          if (fullscreenStatus.value.webfullscreen) {
            state.instance.fullScreen.cancel("web");
          }
        }
        function backFull() {
          if (fullscreenTempStatus.value.fullscreen) {
            state.instance.fullScreen.request("browser");
          }
          if (fullscreenTempStatus.value.webfullscreen) {
            state.instance.fullScreen.request("web");
          }
        }
        context.expose({
          isCanPlay,
          switchVideo,
          seekkVideo,
          getSeekTime,
          setSeekTime,
          play,
          pause,
          cancelFull,
          backFull,
        });
      },
    };
  </script>
  <script>
    const app = createApp({
      components: {
        dplayer: videoPlayer,
      },
      setup() {
        const uuid = guid();
        const dplayerVideo = ref(null);
        const showVideo = ref(false);
        const dplayerObj = reactive({
          video: {
            customType: {
              customHls: function (video, player) {
                const hls = new Hls(); //实例化Hls  用于解析m3u8
                hls.loadSource(video.src);
                hls.attachMedia(video);
              },
            },
          },
        });
        onMounted(() => {
          window.addEventListener("beforeunload", beforeunloadFun, false);
          initVideo();
        });

        function initVideo() {
          let url =
            "https:\/\/******/2023\/04\/12\/100151\/100151.m3u8";
          if (suffix(url) == "m3u8") {
            dplayerObj.video.type = "customHls";
          } else {
            dplayerObj.video.type = "auto";
          }
          dplayerObj.video.url = url;
          showVideo.value = true;
          nextTick(() => {
            dplayerVideo.value = videoBox;
            console.log(dplayerVideo.value);
            dplayerVideo.value.isCanPlay(() => {
              dplayerVideo.value.play();
              timerObj.callback = () => {
                heartBeatApiFun(5);
              };
              timerObj.callback();
              timerObj.setTimer();
            });
          });
        }
        function beforeunloadFun() {
          heartBeatApiFun(4);
        }
        onBeforeUnmount(() => {
          window.removeEventListener("beforeunload", beforeunloadFun, false);
          heartBeatApiFun(4);
          timerObj.removeTimer();
        });
        function videoFinish() {
          heartBeatApiFun(3);
        }
        function heartBeatApi(data) {
          return axios
            .post(
              "https://***************/prod-api/org/paternerStudy/heartBeat",
              data
            )
        }
        function heartBeatApiFun(type, callback = () => { }) {
          const currentVideoTime = parseInt(dplayerVideo.value.getSeekTime());
          heartBeatApi({
            resourceId: "100151",
            currentVideoTime: currentVideoTime,
            // 1播放,2暂停,3结束,4关闭,5定时心跳
            type: type,
            sign: uuid,
            patrtnerCode: "002",
          })
            .then((res) => {
              callback && callback(res);
            })
            .catch((e) => {
            });
        }
        return {
          showVideo,
          dplayerObj,
          videoFinish,
          heartBeatApiFun,
        };
      },
    });



    app.mount("#app");
  </script>
</body>

</html>```

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值