首页 > 其他分享 >uniapp的video组件在层级太高,无法遮挡的问题

uniapp的video组件在层级太高,无法遮挡的问题

时间:2024-01-14 13:11:08浏览次数:41  
标签:uniapp play 层级 val default pause 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

 

标签:uniapp,play,层级,val,default,pause,video,组件
From: https://www.cnblogs.com/ljcgood66/p/17963576

相关文章

  • uniapp---下拉刷新上拉加载
    在用uniapp做APP的时候,下拉刷新,上拉加载是常见的功能需求,现在整理一下: 第一步:设置下拉和上拉属性找到【pages.json】设置:"enablePullDownRefresh":true,"onReachBottomDistance":100,示例: 第二步:页面新增下拉和上拉方法onPullDownRefreshonReachBottom示例:<sc......
  • 技术解密:如何巧妙设计层级结构,轻松解决中间节点删除的挑战?
    嗨,大家好,我是小米!今天我们要聊的话题是一个非常有趣而且挑战性的面试题:“数据是层级结构的,怎么设计方便查询和修改?如果删除中间一个节点,如何保证不改大量数据?”废话不多说,让我们直接跳入这个充满技术乐趣的话题吧!数据结构与层级结构首先,让我们来回顾一下数据结构中的层级结构。在计......
  • VideoDubber:开创性的视频翻译与语音克隆工具
    VideoDubber是一款由生成式人工智能驱动的先进视频翻译和语音克隆工具。它为内容创作者提供了轻松将视频翻译成多种语言的能力,从而触达更广泛的观众。该工具支持多种语言,包括普通话、西班牙语、印地语等。VideoDubber还提供了AI语音克隆功能,让创作者只需单击一下即可克隆他们的声音......
  • PHP+uniapp进销存源码|erp源码计算机毕业设计[附源码]
     企业资源规划(ERP)是一种软件系统,可帮助组织自动化和管理核心业务流程以获得最佳性能。ERP软件协调公司业务流程之间的数据流,提供单一事实来源并简化整个企业的运营。它能够将公司的财务、供应链、运营、商业、报告、制造和人力资源活动连接到一个平台上。 大多数公司都......
  • Vue2 使用 Knova Canvas 合成图片、多个视频、音频在一个画面中并播放,自定义 video co
    本文转载https://blog.csdn.net/RosaChampagne/article/details/128020428?spm=1001.2014.3001.5502的文章安装插件npminstallvue-konva@2konva--save在main.js中使用importVuefrom'vue';importVueKonvafrom'vue-konva';Vue.use(VueKonva);相关实现代......
  • uniapp封装请求拦截和响应拦截的方法
    uniapp封装请求拦截和响应拦截的方法:https://blog.csdn.net/luoxiaonuan_hi/article/details/129731171?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-8-129731171-blog-126888238.235^v40^pc_relevant_3m_sort_dl_base2&spm=10......
  • 如何在uniapp中使用路由进行页面跳转
    Laravel是一个流行的PHP框架,它具有出色的可测试性,可以帮助开发人员在更短的时间内编写可靠的代码。但是,即使使用了这个框架,也可能会出现测试覆盖率较低的情况。测试覆盖率是指代码中已由测试案例覆盖的部分比例。测试覆盖率越高,代码质量越高。在本文中,我们将分享几种技巧,帮助您提......
  • 如何在ECharts中使用矩形树图展示数据层级结构
    Laravel是一个流行的PHP框架,它具有出色的可测试性,可以帮助开发人员在更短的时间内编写可靠的代码。但是,即使使用了这个框架,也可能会出现测试覆盖率较低的情况。测试覆盖率是指代码中已由测试案例覆盖的部分比例。测试覆盖率越高,代码质量越高。在本文中,我们将分享几种技巧,帮助您提......
  • uniapp中如何实现路由跳转动画
    Laravel是一个流行的PHP框架,它具有出色的可测试性,可以帮助开发人员在更短的时间内编写可靠的代码。但是,即使使用了这个框架,也可能会出现测试覆盖率较低的情况。测试覆盖率是指代码中已由测试案例覆盖的部分比例。测试覆盖率越高,代码质量越高。在本文中,我们将分享几种技巧,帮助您提......
  • uniapp微信小程序-底部tabBar颜色显示问题
    uniapp微信小程序-底部tabBar颜色显示问题在HbuilderX上开发的时候,页面运行在H5端的底部tabBar显示都没问题,但在运行到微信开发者工具时出现底部tabBar实际文字颜色与H5效果不同的问题。检查page.json文件。"tabBar":{ "borderStyle":"white", "backgroundColor......