vue中使用swiper轮播实时监控视频并利用video.js播放.m3u8格式监控视频

最近项目遇到一个需求,需要一轮播图的形式展示几个实时的监控视频,这就需要用到swiper和video.js,因为视频格式是m3u8格式的,所以原生video标签不支持

先安装swiper和videojs所需的依赖包
// swiper的包
npm i swiper vue-awesome-swiper
npm i swiper@5
// videojs的包
npm install video.js --save // 视频播放器插件
npm install videojs-contrib-hls  --save // 播放hls流插件
在main.js中引入
// 引入swiper
import 'swiper/swiper-bundle.css'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)
// 引入videojs和样式
import "video.js/dist/video-js.css";
import "videojs-contrib-hls";
使用

不说废话直接上代码

<!-- The ref attr used to find the swiper instance -->
<template>
  <swiper
    :options="swiperOption"
    :not-next-tick="notNextTick"
    ref="mySwiper"
    class="sw"
  >
    <!-- @click="Monitoring" -->
    <!-- slides -->
    <swiper-slide v-for="item,index in monitor" :key="item.id"
      ><div class="monitorItem">
        <div class="imgArea">
          <div class="vidioArea">
            <video
              :id="`my-video${index}`"
              class="video-js vjs-default-skin videos"
              muted
            >
              <source
                :src="item.encryption_height"
                type="application/x-mpegURL"
              />
            </video>
          </div>
          <div class="bottomText">
            <span>{{ item.shop_name }}</span>
          </div>
          <div class="ladder">
            <div class="ladderson">{{ item.title }}</div>
          </div>
        </div>
      </div>
    </swiper-slide>
    <!-- Optional controls -->
    <div class="swiper-pagination" slot="pagination"></div>
    <div class="swiper-button-prev" slot="button-prev" ></div>
    <div class="swiper-button-next" slot="button-next" ></div>
    <div class="swiper-scrollbar" slot="scrollbar"></div>
  </swiper>
</template>

<script>
// swiper options example:
import videojs from "video.js";
import "videojs-contrib-hls";
import loading from "@/components/loading/loading.vue";
export default {
  name: "carrousel",
  data() {
    return {
      monitor: [],
      player: [],
      // notNextTick是一个组件自有属性,如果notNextTick设置为true,组件则不会通过NextTick来实例化swiper,也就意味着你可以在第一时间获取到swiper对象,假如你需要刚加载遍使用获取swiper对象来做什么事,那么这个属性一定要是true
      notNextTick: true,
      swiperOption: {
        // swiper options 所有的配置同swiper官方api配置
        autoplay: 10000, // 自动播放的时间间隔
        slidesPerView: 3, //一次显示的数量
        direction: "horizontal", // 水平轮播
        grabCursor: true,
        setWrapperSize: true,
        autoHeight: true,
        pagination: ".swiper-pagination",
        paginationClickable: true,
        prevButton: ".swiper-button-prev",
        nextButton: ".swiper-button-next",
        scrollbar: ".swiper-scrollbar",
        mousewheelControl: true,
        observeParents: true,
        // if you need use plugins in the swiper, you can config in here like this
        // 如果自行设计了插件,那么插件的一些配置相关参数,也应该出现在这个对象中,如下debugger
        // debugger: true,
        // swiper callbacks
        // swiper的各种回调函数也可以出现在这个对象中,和swiper官方一样
        onTransitionStart(swiper) {
          // console.log(swiper);
        },
        // more Swiper configs and callbacks...
        // ...
      },
    };
  },
  // you can find current swiper instance object like this, while the notNextTick property value must be true
  // 如果你需要得到当前的swiper对象来做一些事情,你可以像下面这样定义一个方法属性来获取当前的swiper对象,同时notNextTick必须为true
  computed: {
    swiper() {
      return this.$refs.mySwiper.swiper;
    },
  },
  mounted() {
    // you can use current swiper instance object to do something(swiper methods)
    // 然后你就可以使用当前上下文内的swiper对象去做你想做的事了
    //   console.log('this is current swiper instance object', this.swiper)
    //   this.swiper.slideTo(3, 1000, false)
    // this.goVideo(this.monitor)
  },
  methods: {
    Monitoring() {
      this.$router.push("/monitoringlive");
    },
    getmonitorList(index){
      this.$axios.post("接口名",{page:index}).then(
        (res)=>{
          if(res.data.code === 200){
            // this.monitor = res.data.data.data
            this.monitor.push(...res.data.data.data)
          console.log(this.monitor);
          this.goVideo(this.monitor)
          }
          console.log(res);
        }
      )
    },
      goVideo(data) {
      this.videoList = data;
      console.log(this.videoList);
      if (data.length == 0) {
        this.$message({
          showClose: true,
          message: "暂无视频~",
        });
      } else {
        // this.videoisShow = true;
        this.$nextTick(() => {
          this.videoList.forEach((item, index) => this.getVideo(index));
        });
      }
    },
    getVideo(i) {
      let res = videojs(
        `my-video${i}`,
        {
          bigPlayButton: true,
          textTrackDisplay: false,
          posterImage: false,
          errorDisplay: false,
          controls: true,
          hls: {
            withCredentials: true,
          },
         controlBar: {
            fullscreenToggle: true,//显示全屏按钮,默认为true
            pictureInPictureToggle: false,//隐藏画中画按钮,默认为true
            volumePanel: false,//隐藏声音面板
            //currentTimeDisplay: true,//显示当前播放时间
            //timeDivider: true,//显示时间分割线
            //durationDisplay: true,//显示总时间
            //remainingTimeDisplay: false,//隐藏剩余时间,
        }
        },
        function () {
          this.play();
        }
      );

      this.player.push(res);
    },
    videoClose() {
      this.player.forEach((item) => item.dispose());
      this.player = [];
      this.videoList = [];
    },
  },
  components: {
    // loading,
    videojs,
  },
  created () {
    this.getmonitorList(1)
     var timer = 0
    this.echartsset = setInterval(() => {
      timer++
      this.getmonitorList(2);
      if(timer === 1){
        clearInterval(this.echartsset)
      }
    }, 10000);
  },
  beforeDestroy(){
    this.videoClose()
  }
};
</script>

<style scoped lang = "less">
/* sw为自己定义的样式 */
/* .sw {
  --swiper-navigation-size:0;
}  */
/* .sw img {
  height: 270px;
  width: 95%;
}  */
.monitorItem {
  margin: 15px;
  cursor: pointer;
  border: 5px solid rgb(1, 114, 255);
  .imgArea {
    position: relative;
    width: 100%;
    height: 100%;
    .bottomText {
      font-size: 12px;
      /* position: absolute; */
      left: 0;
      bottom: -10px;
      width: 100%;
      color: white;
      text-align: center;
      background-color: rgba(0, 0, 0, 0.5);
       white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .ladder {
      position: absolute;
      top: 0;
      left: 0;
      width: 40px;
      height: 0;
      border-top: 20px solid rgb(1, 114, 255);
      border-right: 20px solid transparent;
      text-align: center;
      .ladderson {
        color: #fff;
        font-size: 12px;
        margin-top: -18px;
        /* margin-left: 3px; */
      }
    }
  }
}
.sw img[data-v-31d8b10e] {
  height: 100%;
  width: 100%;
}
.swiper-button-prev,
.swiper-button-next {
  width: calc(var(--swiper-navigation-size) / 44 * 0);
  font-weight: 1000;
}
.swiper-button-prev:after,
.swiper-button-next:after {
  font-size: 35px;
}
.videos {
  width: 100%;
  height: 120px;
  object-fit: cover;
}
.video-js .vjs-tech .videos{
  width: 100%;
  /* height: 100%; */
  object-fit: cover;
}
</style>
最终效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值