完美解决uni-app打开页面无法自动播放视频的问题

video.vue

<template>
  <view class="index">

    <index-header bgColor="bg-index-header" @headerSwitch="headerSwitch"/>

    <!-- 视频组件 -->
    <cu-video class="video" :video_list="videoList"/>

  </view>
</template>

<script>
import indexHeader from './index-header.vue';
import cuVideo from './cu-video.vue';
export default {
  components: {
    indexHeader,
    cuVideo
  },
  data() {
    return {
      title: 'Hello',
      videoList:[],
    }
  },
  onLoad() {
    this.getVideoList();
  },
  onShow() {
    console.log('界面显示')
    uni.$emit('onShow', 1);
  },
  methods: {

    getVideoList(refresh) {
      let list = [
        {
          video_id: 1,
          nickname: '小明',
          video_describe: '这是视频描述',
          cover_url: '/static/video/1-1.mp4',
          video_url: '/static/video/1-1.mp4',
          dianzan: 0,
          pinglun: 0,
          zhuanfa: 0,
          is_dianzan: false
        },
        {
          video_id: 2,
          nickname: '小明',
          video_describe: '这是视频描述',
          cover_url: '/static/video/1-2.mp4',
          video_url: '/static/video/1-2.mp4',
          dianzan: 0,
          pinglun: 0,
          zhuanfa: 0,
          is_dianzan: false
        },
        {
          video_id: 3,
          nickname: '小明',
          video_describe: '这是视频描述',
          cover_url: '/static/video/1-3.mp4',
          video_url: '/static/video/1-3.mp4',
          dianzan: 0,
          pinglun: 0,
          zhuanfa: 0,
          is_dianzan: false
        },
        {
          video_id: 4,
          nickname: '小明',
          video_describe: '这是视频描述',
          cover_url: '/static/video/1-4.mp4',
          video_url: '/static/video/1-4.mp4',
          dianzan: 0,
          pinglun: 0,
          zhuanfa: 0,
          is_dianzan: false
        },
        {
          video_id: 5,
          nickname: '小明',
          video_describe: '这是视频描述',
          cover_url: '/static/video/1-5.mp4',
          video_url: '/static/video/1-5.mp4',
          dianzan: 0,
          pinglun: 0,
          zhuanfa: 0,
          is_dianzan: false
        },
      ]
      for (let item of list) {
        this.videoList.push({
          video_id: item.video_id,
          nickname: item.nickname,
          video_describe: item.video_describe,
          cover_url: item.cover_url,
          video_url: item.video_url,
          dianzan: item.dianzan,
          pinglun: item.pinglun,
          zhuanfa: item.zhuanfa,
          is_dianzan: item.is_dianzan,
          flag: false
        });
      }
    },
    // 顶部切换
    headerSwitch(val){
      // console.log(val);
      this.getVideoList();
    }




  }

}
</script>

<style lang="scss" scoped>
.index {
  display: flex;
  flex-direction: column;
  /* align-items: center; */
  justify-content: center;
  background-color: #333333;
  height: 100vh;
}
.tabbar{
  .action{
    .plus{
      image{
        width: 100upx;
        height: 60upx;
      }
    }
  }
}
</style>
复制代码
cu-video.vue
<template>
  <view>
    <swiper class="swiper" autoplay="false" vertical="true" interval="990000" @change="changeVideo">
      <swiper-item v-for="(item,index) in video_list">

        <video
            webkit-playsinline
            :src="item.video_url"
            preload
            show-play-btn="true"
            show-mute-btn="true"
            controls="true"
            :autoplay="false"
            loop="true"
            :id="`video_${item.video_id}`"
            objectFit="fill"
            :enable-progress-gesture="false"
            @click="clickVideo"
            ref="video_url"
            play-btn-position="center"
            @loadedmetadata="handleVideoReady"
            class="video"
            :poster="item.cover_url"
            @timeupdate="timeupdate">
        </video>

        <cover-image
            class="play" v-if="show_play"
            @tap="videoPlay"
            src="/static/video/play_1.png"></cover-image>

        <cover-view class="cover-view-left">
          <text class="view-left-text">@{{ item.nickname }}</text>
          <view class="view-left-text-content">
            <text class="text-content-text">{{ item.video_describe }}</text>
          </view>
        </cover-view>

        <cover-view class="cover-view-right">
          <cover-image :src="item.cover_url"
                       class="avater img"
                       @click.stop="tapAvater"></cover-image>

          <text class="right-follow">+</text>
          <cover-image
              style="position:relative;top:-20upx;"
              :src="item.is_dianzan ? '/static/video/axc.png' : '/static/video/bed.png'"
              class="img-left" @click.stop="tapLove"></cover-image>

          <text class="right-text">{{ item.dianzan }}</text>
          <cover-image src="/static/video/ay2.png"
                       style="height: 80upx;" class="img-left" @click.stop="tapMsg"></cover-image>

          <text class="right-text">{{ item.pinglun }}</text>
          <cover-image src="/static/video/b6p.png"
                       style="height: 76upx;" class="img-left" @click.stop="tapShare"></cover-image>

          <text class="right-text">{{ item.zhuanfa }}</text>
          <cover-image src="/static/video/changpian.png" class="musicIcon img">
          </cover-image>

          <cover-view class="progressBar" :animation="animationData" :style="`width:${barWidth}px`"></cover-view>


        </cover-view>

      </swiper-item>
    </swiper>
  </view>
  <view>
    <!-- 提示窗示例 -->
    <uni-popup ref="alertDialog" type="dialog">
      <uni-popup-dialog type="success" cancelText="关闭" confirmText="同意" title="通知" content="欢迎使用 uni-popup!" @confirm="dialogConfirm"
                        @close="dialogClose"></uni-popup-dialog>
    </uni-popup>
  </view>
</template>
<script >
import wx from 'weixin-js-sdk';

let play = true;
export default {
  props: {
    video_list: {
      type: Array,
      default: {},
    },
    app_show_play: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      time: 0,
      barWidth:0,
      animationData: {},
      times:null,
      play: false,
      show_play:this.app_show_play,
      current_index: 0
    };
  },
  created() {
    setTimeout(()=>{
      this.videoPause()
      play = true;
      this.$nextTick(()=>{
        this.videoPlay();
      })
    },1000)
  },
  onHide() {
  },
  mounted(){
    // this.$refs.alertDialog.open()
    const that = this;
    uni.$on('onShow', function(data) {
      //解决再次打开时,播放视频
      if(data == 1){
        that.videoPause()
        play = true;
        that.$nextTick(()=>{
          that.videoPlay();
        })
      }
    });
  },
  onReady(){
  },
  onUnload(){
    // this.videoPause();
  },
  onShow(){
    alert("12133")
  },
  methods: {
    timeupdate(event) {
      let t_w = parseInt(this.width);
      this.duration = event.detail.duration;
      this.time = event.detail.currentTime;
      let width = (this.time / this.duration) * t_w;
      let w = 0;
    },
    clickVideo() {
      // console.log('单视频点击事件');
      this.videoPlay();
    },
    videoPlay() {
      let video_id = this.video_list[this.current_index].video_id;
      if (play) {
        console.log('播放视频',`video_${video_id}`);
        this.videoCtx = uni.createVideoContext(`video_${video_id}`, this);
        this.videoCtx.play();
        this.show_play = false;
        play = false;
      } else {
        console.log('暂停视频',`video_${video_id}`);
        this.videoCtx = uni.createVideoContext(`video_${video_id}`, this);
        this.videoCtx.pause();
        this.show_play = true;
        play = true;
      }
    },
    videoPause() {
      let video_id = this.video_list[this.current_index].video_id;
      this.videoCtx = uni.createVideoContext(`video_${video_id}`, this);
      this.videoCtx.pause();
      this.show_play = true;
      play = true;
    },
    changeVideo(e){

      // 暂停之前的视频
      this.videoPause();
      this.current_index = e.detail.current;
      console.log(e.detail.current);
      // 播放现在的视频
      this.videoPlay();

      // 判断是否第一条
      if( e.detail.current == 0 ){
        console.log('到顶了');
        return false;
      }

      // 判断是否最后一条
      if( e.detail.current == this.video_list.length-1 ){
        console.log('到底了');
        return false;
      }

    },
    tapMsg(e) {
      console.log(5, e);
    },
    tapShare(e) {
      console.log(6, e);
    },
    tapLove(e) {
      // item.is_dianzan
      this.video_list[this.current_index].is_dianzan = !this.video_list[this.current_index].is_dianzan;
      console.log(7, e);
    },
    handleVideoReady(){
      console.log('视频加载完成');
    },
    dialogConfirm() {
      console.log('点击确认')
      this.play = true;
      this.videoPlay();
    },
    dialogClose(){
      this.play = true;
      this.videoPlay();
    }

  },
  watch: {
    play(newVal, oldVal) {
      this.videoPlay();
    }
  }
};
</script>

<style lang="scss" scoped>
.swiper{
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
}
.video {
  width: 100%;
  height: 100%;
  position: relative;
}
.play{
  position: absolute;
  width: 20vw;
  height: 20vw;
  left: 40vw;
  top: 40vh;
  opacity: 0.5;
}
.progressBar {
  border-radius: 2upx;
  height: 4upx;
  background-color: #FF4500;
  z-index: 999999;
  position: absolute;
  bottom: 68rpx;
}

.cover-view-left {
  position: absolute;
  margin-left: 20upx;
  width: 580upx;
  bottom: 110upx;
  z-index: 9999;
  font-size: 14px;
  color: #ffffff;
}
.left-text {
  font-size: 14px;
  color: #ffffff;
}

.cover-view-right {
  position: absolute;
  bottom: 40px;
  right: 30upx;
  z-index: 9999;
  text-align: center;
}

.avater {
  border-radius: 50%;
  border-width: 2px;
  border-style: solid;
  border-color: #ffffff;
}

.img {
  height: 90upx;
  width: 90upx;
  margin-bottom: 110upx;
}

.img-left {
  width: 80upx;
  height: 66upx;
  padding-left: 4px;
}
.right-follow {
  position: absolute;
  z-index: 100;
  top: 75upx;
  left: 28upx;
  color: #ffffff;
  font-size: 16px;
  width: 34upx;
  height: 34upx;
  background-color: #f12f5b;
  text-align: center;
  line-height: 34upx;
  border-radius: 17upx;
}

.right-text {
  color: #ffffff;
  font-size: 11px;
  text-align: center;
  margin-bottom: 40upx;
}
.musicIcon {
  margin-top: 40upx;
}
@keyframes rotating {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(360deg);
  }
}
.view-left-text-content {
  flex: 1;
}
.view-left-text {
  color: #ffffff;
  font-size: 18px;
  margin-bottom: 10upx;
  font-weight: bold;
}
.text-content-text {
  color: #ffffff;
  font-size: 16px;
  line-height: 50upx;
  height: 100upx;
  overflow: hidden;
}
</style>
1.以上分别是播放视频的页面,初次加载因为浏览器防打扰机制的问题,所以限制的播放,可以通过先暂停视频,然后在播放视频的方式解决自动播放的问题
2.再次打开标签页时发现视频又不能再次播放,通过父组件通信告诉子组件打开播放之前暂停的视频即可解决
相关推荐
Fantasywt2 小时前
THREEJS 片元着色器实现更自然的呼吸灯效果
前端·javascript·着色器
EasyCVR2 小时前
EasyRTC嵌入式视频通话SDK的跨平台适配,构建web浏览器、Linux、ARM、安卓等终端的低延迟音视频通信
android·arm开发·网络协议·tcp/ip·音视频·webrtc
IT、木易2 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
张拭心5 小时前
2024 总结,我的停滞与觉醒
android·前端
念九_ysl5 小时前
深入解析Vue3单文件组件:原理、场景与实战
前端·javascript·vue.js
Jenna的海糖5 小时前
vue3如何配置环境和打包
前端·javascript·vue.js
星之卡比*5 小时前
前端知识点---库和包的概念
前端·harmonyos·鸿蒙
灵感__idea5 小时前
Vuejs技术内幕:数据响应式之3.x版
前端·vue.js·源码阅读
烛阴5 小时前
JavaScript 构造器进阶:掌握 “new” 的底层原理,写出更优雅的代码!
前端·javascript
Alan-Xia5 小时前
使用jest测试用例之入门篇
前端·javascript·学习·测试用例