uniapp的video組件在層級太高,無法遮擋的問題

uniapp-vue項目中需要播放視頻,uniapp的video組件在層級太高,無法遮擋,所以使用原生dom的video標籤在APP中播放視頻,可以被其他元素進行覆蓋、遮擋,頁面具有更高的定製性

<!-- eslint-disable -->
<template>
  <view
    v-html="videoHtml"
    id="dom-video"
    class="dom-video"
    :eventDrive="eventDrive"
    :change:eventDrive="domVideo.eventHandle"
    :videoSrc="videoSrc"
    :change:videoSrc="domVideo.srcChange"
    :videoProps="videoProps"
    :change:videoProps="domVideo.propsChange"
    :randomNum="randomNum"
    :change:randomNum="domVideo.randomNumChange"
  />
</template>

<script>
export default {
  props: {
    src: {
      type: String,
      default: '',
      // 'http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4',
      // 'https://www.w3school.com.cn/i/movie.ogg',
      // 'https://cesium.com/public/SandcastleSampleData/big-buck-bunny_trailer.mp4',
    },
    autoplay: {
      type: Boolean,
      default: false,
    },
    loop: {
      type: Boolean,
      default: false,
    },
    controls: {
      type: Boolean,
      default: false,
    },
    objectFit: {
      type: String,
      default: 'contain',
    },
    muted: {
      type: Boolean,
      default: false,
    },
    poster: {
      type: String,
      default: '',
    },
  },

  // 數據狀態
  data() {
    return {
      videoHtml: '',
      videoSrc: '',
      eventDrive: null,
      videoProps: {},
      randomNum: Math.floor(Math.random() * 100000000 + 1),
    };
  },
  watch: {
    // 監聽視頻資源文件更新
    src: {
      handler(val) {
        if (!val) return;
        this.initVideoHtml();
        setTimeout(() => {
          this.videoSrc = val;
        }, 0);
      },
      immediate: true,
    },
    // 監聽首次加載
    autoplay: {
      handler(val) {
        this.videoProps.autoplay = val;
      },
      immediate: true,
    },
  },
  // 生命週期
  mounted() {
    this.initVideoHtml();
  },

  // 方法
  methods: {
    // 將video的事件傳遞給父組件
    videoEvent(data) {
      console.log('向父組件傳遞事件 =>', data);
      if (data === 'pause') {
        // 特定處理  iOS
        this.eventDrive = 'play';
      }
      this.$emit(data);
    },
    // 初始化視頻
    initVideoHtml() {
      this.videoHtml = `<video
          src="${this.src}"
          id="dom-html-video_${this.randomNum}"
          class="dom-html-video"
          ${this.autoplay ? 'autoplay' : ''}
          ${this.loop ? 'loop' : ''}
          ${this.controls ? 'controls' : ''}
          ${this.muted ? 'muted' : ''}
          ${this.poster ? 'poster="' + this.poster + '"' : ''}
          preload="auto"
          playsinline
          webkit-playsinline
          width="100%"
          height="100%"
          style="object-fit: ${this.objectFit};padding:0;"
        >
          <source src="${this.src}" type="video/mp4">

        </video>
      `;
      console.log('視頻html =>', this.videoHtml);
    },
    resetEventDrive() {
      this.eventDrive = null;
    },
    // 將service層的事件/數據 => 傳遞給renderjs層
    play() {
      this.eventDrive = 'play';
    },
    pause() {
      console.log('向父組件傳遞事件3 =>0');
      this.eventDrive = 'pause';
    },
    stop() {
      this.eventDrive = 'stop';
    },
  },
};
</script>

<script module="domVideo" lang="renderjs">
export default {
  data() {
    return {
      video: null,
      num: '',
      options: {}
    }
  },
  mounted() {
    this.initVideoEvent()
  },
  methods: {
    initVideoEvent() {
      setTimeout(() => {
        let video = document.getElementById(`dom-html-video_${this.num}`)
        this.video = video

        // 監聽視頻事件
        video.addEventListener('play', () => {
          this.$ownerInstance.callMethod('videoEvent', 'play')
        })
        video.addEventListener('pause', () => {
            console.log('向父組件傳遞事件3 =>');
          this.$ownerInstance.callMethod('videoEvent', 'pause')
        })
        video.addEventListener('ended', () => {
          this.$ownerInstance.callMethod('videoEvent', 'ended')
          this.$ownerInstance.callMethod('resetEventDrive')
        })
      }, 100)
    },
    eventHandle(eventType) {
      if (eventType) {
        this.video = document.getElementById(`dom-html-video_${this.num}`)
console.log('向父組件傳遞事件32 =>');
        if (eventType === 'play') {
          this.video.play()
        } else if (eventType === 'pause') {
            console.log('向父組件傳遞事件31 =>');
          this.video.pause()
        } else if (eventType === 'stop') {
          this.video.stop()
        }
      }
    },
    srcChange(val) {
      // 實現視頻的第一幀作爲封面,避免視頻展示黑屏
      this.initVideoEvent()
      setTimeout(() => {
        let video = document.getElementById(`dom-html-video_${this.num}`)

        video.addEventListener('loadedmetadata', () => {
          let { autoplay } = this.options
          video.play()
          if (!autoplay) {
            video.pause()
          }
        })
      }, 0)
    },
    propsChange(obj) {
      this.options = obj
    },
    randomNumChange(val) {
      this.num = val
    },
  }
}
</script>

<style lang="scss" scoped>
.dom-video {
  overflow: hidden;
  height: 100%;
  padding: 0;
  &-height {
    height: 100%;
  }
}
</style>

使用方法:

<view class="">
          <dom-video
            :key="i"
            ref="domVideo"
            :class="{ playing: n.playing }"
            class="animation-container"
            v-if="state.botInfo[n.urlField]"
            object-fit="cover"
            :controls="false"
            :show-progress="false"
            :show-fullscreen-btn="false"
            :show-play-btn="false"
            :show-bottom-progress="false"
            :show-loading="false"
            :enable-progress-gesture="false"
            :enable-play-gesture="false"
            :auto-pause-if-navigate="false"
            :auto-pause-if-open-native="false"
            :autoplay="true"
            :loop="true"
            :muted="true"
            :show-controls="false"
            :style="{
              opacity: !n.visibleField || state[n.visibleField] ? '1' : '0',
            }"
            :src="state.botInfo[n.urlField]"
            @play="n.playing = true"
            @pause="videoPause"
            @ended="videoEnded"
          />
        </view>

來源地址:https://ext.dcloud.net.cn/plugin?id=11304

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章