uniapp安卓App端,视频+图片轮播,层级过高及卡顿问题

1,问题:使用uniapp打包安卓app,在使用轮播图的过程中,如果使用纯图片或者纯视频,轮播是没有问题的。

但是,如果使用视频+图片的形式轮播的话,返回视频会出现卡顿,扭曲,变形等问题,或者是只能看到半个视频,而且不同型号的手机端,时好时坏,看着很是不爽。具体问题如图

在这里插入图片描述

2,出现问题的原因是:

由于在uniapp中video属于原生,层级很高,即使设置z-index也不可行。在和图片一起轮播的过程中还是会出现那个卡顿问题:
主要是在swiper中嵌套video,会受到scroll-view的影响,视频发生错位。
所以解决这个问题,就很脑壳疼。
陆陆续续尝试了好几种方法,就是不行。

3,解决方法

覆盖其需要使用cover-view组件或plus.nativeObj.view、subNVue
cover-view
subNVue
plus.nativeObj.view

参考:
plus.nativeObj.view与subNvue的解决方法
添加video属性解决方法
控制video的显示和隐藏

简单看了几种方法,网上的文档较为杂乱,简单梳理了一下,排除了重重万难,费了九牛二虎之力,最终使用cover-view和video的显示隐藏实现了这个轮播。

4,先看看组件在页面中的使用:

a.引入

  import ProductConSwiper from "@/components/ProductConSwiper";

b.调用

<view class="auto-video">
<product-con-swiper :img-urls="storeInfo.sliderImageArr" ></product-con-swiper>
</view>

由于需要加入视频,则给组件新添绑定mpvideo

<view class="auto-video">
<product-con-swiper :img-urls="storeInfo.sliderImageArr" :mpvideo="storeInfo.video"></product-con-swiper>
</view>

c.原组件

<template>
  <view class="slider-banner product-bg">
    <swiper class="swiper-wrapper" @change="handleChange" v-if="imgUrls.length > 0">
      <block v-for="(item, imgUrlsIndex) in imgUrls" :key="imgUrlsIndex">
        <swiper-item>
          <image :src="item" class="slide-image" />
        </swiper-item>
      </block>
    </swiper>
    <!-- <swiper class="swiper-wrapper" :options="ProductConSwiper" v-if="imgUrls.length > 0">
      <swiperSlide class="swiper-slide" v-for="item in imgUrls" :key="item" ref="goodSwiper">
        <image :src="item" class="slide-image" />
      </swiperSlide>
    </swiper>-->
    <view class="pages">{{ currents || 1 }}/{{ imgUrls.length || 1 }}</view>
  </view>
</template>
<script>
// import { swiper, swiperSlide } from "vue-awesome-swiper";

export default {
  name: "ProductConSwiper",
  components: {
    // swiper,
    // swiperSlide
  },
  props: {
    imgUrls: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    let that = this;
    return {
      currents: 1,
      ProductConSwiper: {
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true,
        on: {
          slideChangeTransitionStart: function() {
            that.currents = this.realIndex + 1;
          }
        }
      }
    };
  },
  mounted: function() {},
  methods: {
    handleChange(event) {
      this.currents = event.mp.detail.current + 1;
    }
  }
};
</script>

5.加入cover-view

加入视频

   <swiper-item id="canvas" @change="change" v-if="!hiddenVideo">
          <!--原视频-->
          <video
            id="myVideo"
            :src="mpvideo"
            class="slide-image"
            style="position: relative; width: 100%; height: 100%"
            controls
            show-progress
            :enable-play-gesture="false"
            preload="true"
            webkit-playsinline="true"
            playsinline="true"
            x5-video-player-type="h5"
            x5-video-orientation="portraint"
            x-webkit-airplay="true"
            x5-video-player-fullscreen=""
          >
          </video>
        </swiper-item>

加入cover-view覆盖视频,两段视频是由于返回时错位。

 <swiper-item id="canvas" @change="change" v-if="!hiddenVideo">
          <!--原视频--><!--覆盖-->
          <video
            id="myVideo"
            :src="mpvideo"
            class="slide-image"
            style="position: relative; width: 100%; height: 100%"
            controls
            show-progress
            :enable-play-gesture="false"
            preload="true"
            webkit-playsinline="true"
            playsinline="true"
            x5-video-player-type="h5"
            x5-video-orientation="portraint"
            x-webkit-airplay="true"
            x5-video-player-fullscreen=""
            @click="testVideo"
          >
            
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              class="slide-image"
              @click="toNext"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            ></cover-view>
          </video>
        </swiper-item>

        <swiper-item id="canvas" @change="change" style="position: absoulte">
          <!--原视频-->
          <video
            id="myVideo"
            :src="mpvideo"
            class="slide-image"
            style="position: relative; width: 100%; height: 100%"
            controls
            show-progress
            :enable-play-gesture="false"
            preload="true"
            webkit-playsinline="true"
            playsinline="true"
            x5-video-player-type="h5"
            x5-video-orientation="portraint"
            x-webkit-airplay="true"
            x5-video-player-fullscreen=""
            v-if="!hiddenVideo"
            @click="testVideo"
          >
            <!--覆盖-->
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              class="slide-image"
              @click="toNext"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            ></cover-view>
          </video>
        </swiper-item>

给图片也加上

        <swiper-item @change="change">
          <image
            :src="item"
            class="slide-image"
            v-if="(autoplay = true)"
            click="reload"
          >
          </image>

          <!--覆盖v-if="!hiddenVideo"-->
          <div
            v-if="!hiddenVideo"
            style="position: relative; width: 100%; height: 100%"
          >
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            >
            </cover-view>
            <cover-image :src="item" v-if="(autoplay = true)"> </cover-image>
          </div>
        </swiper-item>

6.判断视频播放和轮播

  created() {
    // 创建视频实例指向视频控件
    this.videoContext = uni.createVideoContext("myVideo");
  },
 methods: {
    toNext() {
      this.playVideo = !this.playVideo;
      this.istoNext = false;
      if (this.playVideo) {
        this.videoContext.play(); //播放视频
        console.log("视频播放", this.playVideo);
      }
      if (!this.playVideo) {
        this.videoContext.pause(); //停止视频
        this.istoNext = true;
        if (!this.playVideo && this.istoNext == true) {
          this.current = 1;
          console.log("停止视频", this.playVideo);
        }
      }
    },
     handleChange(event) {
      this.currents = event.mp.detail.current + 1;
      if (this.currents == 1) {
        this.current = 0;
        this.hiddenVideo = false;
        console.log("视频播放");
      } else if (this.currents == 2) {
        this.hiddenVideo = true; //轮播卡顿,隐藏视频
        console.log("轮播图片");
      }
    },
    }

全部代码

<template >
  <view class="slider-banner product-bg" id="popup">
    <swiper
      class="swiper-wrapper"
      @change="handleChange"
      v-if="imgUrls.length > 0"
      :current="current"
    >
      <block v-for="(item, imgUrlsIndex) in imgUrls" :key="imgUrlsIndex">
        <swiper-item id="canvas" @change="change" v-if="!hiddenVideo">
          <!--原视频--><!--覆盖-->
          <video
            id="myVideo"
            :src="mpvideo"
            class="slide-image"
            style="position: relative; width: 100%; height: 100%"
            controls
            show-progress
            :enable-play-gesture="false"
            preload="true"
            webkit-playsinline="true"
            playsinline="true"
            x5-video-player-type="h5"
            x5-video-orientation="portraint"
            x-webkit-airplay="true"
            x5-video-player-fullscreen=""
            @click="testVideo"
          >
            
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              class="slide-image"
              @click="toNext"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            ></cover-view>
          </video>
        </swiper-item>

        <swiper-item id="canvas" @change="change" style="position: absoulte">
          <!--原视频-->
          <video
            id="myVideo"
            :src="mpvideo"
            class="slide-image"
            style="position: relative; width: 100%; height: 100%"
            controls
            show-progress
            :enable-play-gesture="false"
            preload="true"
            webkit-playsinline="true"
            playsinline="true"
            x5-video-player-type="h5"
            x5-video-orientation="portraint"
            x-webkit-airplay="true"
            x5-video-player-fullscreen=""
            v-if="!hiddenVideo"
            @click="testVideo"
          >
            <!--覆盖-->
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              class="slide-image"
              @click="toNext"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            ></cover-view>
          </video>
        </swiper-item>

        <!--原图片-->
        <swiper-item @change="change">
          <image
            :src="item"
            class="slide-image"
            v-if="(autoplay = true)"
            click="reload"
          >
          </image>

          <!--覆盖v-if="!hiddenVideo"-->
          <div
            v-if="!hiddenVideo"
            style="position: relative; width: 100%; height: 100%"
          >
            <cover-view
              style="color: #3b91f8; z-index: 99999"
              @touchstart="start"
              @touchend="end"
              @touchmove="move"
              :style="{
                transform: 'translateX(' + moveX + 'px)',
              }"
            >
            </cover-view>
            <cover-image :src="item" v-if="(autoplay = true)"> </cover-image>
          </div>
        </swiper-item>
        <!-- <swiper-item @change="change">
          <div class="slide-image">
            <image
              :src="item"
              class="slide-image"
              v-if="(autoplay = true)"
            ></image>
            <view class="pages"
              >{{ currents || 1 }}/{{ imgUrls.length + 1 || 1 }}</view
            >
          </div>
        </swiper-item> -->
      </block>
    </swiper>
    <!-- <swiper class="swiper-wrapper" :options="ProductConSwiper" v-if="imgUrls.length > 0">
      <swiperSlide class="swiper-slide" v-for="item in imgUrls" :key="item" ref="goodSwiper">
        <image :src="item" class="slide-image" />
      </swiperSlide>
    </swiper>-->
    <view class="pages">{{ currents || 1 }}/{{ imgUrls.length + 1 || 1 }}</view>
  </view>
</template>
<script>
// import { swiper, swiperSlide } from "vue-awesome-swiper";

export default {
  name: "ProductConSwiper",
  components: {
    // swiper,
    // swiperSlide
  },
  props: {
    imgUrls: {
      type: Array,
      default: () => [],
    },
    mpvideo: "",
  },
  data: function () {
    let that = this;
    return {
      currents: 1,
      current: 0,
      //@kk add
      startData: {
        clientX: "",
        clientY: "",
      },
      moveX: 0,
      touch: {},
      pages: 0,
      istoNext: false,
      ProductConSwiper: {
        autoplay: {
          disableOnInteraction: false,
          delay: 2000,
        },
        loop: true,
        hiddenVideo: true,
        playVideo: false, //是否显示cover
        speed: 1000,
        observer: true,
        observeParents: true,
        timer: "",
        on: {
          slideChangeTransitionStart: function () {
            that.currents = this.realIndex + 1;
            cosnsole.log(realIndex, "Index");
            // that.currents
          },
        },
      },
    };
  },
  created() {
    // 创建视频实例指向视频控件
    this.videoContext = uni.createVideoContext("myVideo");
  },
  mounted: function () {},
  methods: {
      //点击视频播放,[cover隐藏],视频触发播放。
      //点击视频停止,[cover出现],滚动到下一张图片。
    toNext() {
      this.playVideo = !this.playVideo;
      this.istoNext = false;
      if (this.playVideo) {
        this.videoContext.play(); //播放视频
        console.log("视频播放", this.playVideo);
      }
      if (!this.playVideo) {
        this.videoContext.pause(); //停止视频
        this.istoNext = true;
        if (!this.playVideo && this.istoNext == true) {
          this.current = 1;
          console.log("停止视频", this.playVideo);
        }
      }
    },
    handleChange(event) {
      this.currents = event.mp.detail.current + 1;
      if (this.currents == 1) {
        this.current = 0;
        this.hiddenVideo = false;
        console.log("视频播放");
      } else if (this.currents == 2) {
        this.hiddenVideo = true; //轮播卡顿,隐藏视频
        console.log("轮播图片");
      }
    },
    change(e) {
      console.log(e, "轮播");
      debugger;
      this.videoContext.pause();
    },

  },
};
</script>
<style lang="less" scoped>
/deep/ .uni-video-slots {
  z-index: 1;
}
</style>


7.历尽千辛万苦,一顿操纵猛如虎,最终完美解决!!!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐