Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
🎯 preface
Video playback may not be much in daily business scenarios, but it is definitely not strange, choose a good plug-in often get twice the result with half the effort. Today, I will present a scenario to introduce bytedance’s open source watermelon player, which has many powerful functions 😎.
This article uses Vue+Xgplayer
🎯 Expected Effect
Watermelon videos have this preview effect (many video sites have it), and that’s what we’re going to do today
🎯 Final Effect
Xgplayer is easy to use
Install xgplayer
npm install xgplayer
Copy the code
Import and initialize the required VUE components
import Player from 'xgplayer'
let player = new Player({
id:' ' , // The id of the tag or use the el:dom element
url: video url,videoInit: true.poster: Cover art,controls: false.playbackRate: [0.5.0.75.1.1.5.2].whitelist: [
' '].fluid: false.// download: true,
width: '100%'.height: '200px'
})
Copy the code
This creates a video player that can be created in the specified container.
🎯 Implementation Idea
In the full effect above, this case is obviously looping out multiple containers. Here we need to consider the problem of creating one or more Player instances. There are two ways of thinking about this, and this article uses the first one. By the way, in real business, data comes from interface services (the pit is here).
1. Create multiple containers in a loop and create instances for each container. To avoid this, use pagination.
2. Circular create container, do not create an instance, only show the cover, when moving into the container to destroy the previous instance, create the current instance (better solution), readers can try.
According to the effect, it is not difficult to see that the video is playing when moving into the container, and the current video is paused when moving out, so that only one is playing at the same time. I have prepared an IMG cover layer and a video layer, the default display image layer, using two events mouseEnter and mouseleave to dynamically control the display and hide of the corresponding container (there is also a pit), and the corresponding index instance operation (pause, destroy, etc.).
startPlay(data,index){
this.$refs['img'+index][0].style.display="none"
this.$refs['video'+index][0].style.display="block"
this.$nextTick(() = >{
this.dom[index].play()
})
},
move(data,index){
this.$refs['img'+index][0].style.display="block"
setTimeout(() = > {
this.dom[index].pause()
}, 0);
this.$refs['video'+index][0].style.display="none"
},
Copy the code
🎯 Full code
Copy the code
<template>
<div class="video">
<div class="video-content" id="videoScroll" ref="videoScrollBar">
<div class="card" v-for="(item,index) in videoList" :key="index" >
<div style="width:100%; height:200px"
@mouseenter="startPlay(item,index)"
@mouseleave="move(item,index)">
<div
:ref="`img${index}`"
style="width:100%; height:200px; background-size: cover;"
:style="{'background-image':`url(${item.spsltlj+'/'+item.spslt}) `}">
</div>
<div style="display:none; overflow:hidden" :ref="`video${index}`">
</div>
</div>
<div class="title">
{{item.spmc}}
</div>
</div>
</div>
</div>
</template>
<script>
import Player from 'xgplayer'
import { loadVideoList } from "@/api/video"
export default {
name: 'Video'.components: {
TitleField: Title
},
data () {
return {
videoList: [].dom: [].}},created() {
this.setBaseList()
},
mounted(){},methods: {
async setBaseList(){
const res =await loadVideoList(this.form)
this.videoList=res.data.records
setTimeout(() = > {
if(this.videoList.length){
this.videoList.forEach((item,index) = >{
this.init(item,index)
},1000)}else{
this.dom.length=0
}
})
},
init (data,index) {
this.dom[index]= new Player({
el: this.$refs['video'+index][0].url: data.splj+'/'+data.spbh,
videoInit: true.poster:data.spsltlj+'/'+data.spslt,
// cssFullscreen: true,
lang: 'zh-cn'.controls: false.playbackRate: [0.5.0.75.1.1.5.2].whitelist: [
' '].ignores: ['play'].fluid: false.// download: true,
width: '100%'.height: '200px'})},startPlay(data,index){
this.$refs['img'+index][0].style.display="none"
this.$refs['video'+index][0].style.display="block"
this.$nextTick(() = >{
this.dom[index].play()
})
},
move(data,index){
this.$refs['img'+index][0].style.display="block"
setTimeout(() = > {
this.dom[index].pause()
}, 0);
this.$refs['video'+index][0].style.display="none"}}},</script>
<style scoped lang = "less">
.card{
width: 18%;
margin: 0 20px 20px 0;
float: left;
}
.title{
width: 100%;
color: # 000;
height:40px;
line-height: 40px;
background-color: #ffffff;
font-weight: 600;
padding-left: 10px;
}
</style>
Copy the code
🎯 Two pits
🫀 problem with initializing instances before data has been loaded
Here, the timer is used for delayed execution. If the loop is directly circulated, the watermelon player will report an error when playing, which basically means that the instance has not been initialized. Similarly, the play method should be called to play the event after dom loading is completed.
async setBaseList(){
const res =await loadVideoList(this.form)
this.videoList=res.data.records
setTimeout(() = > {
if(this.videoList.length){
this.videoList.forEach((item,index) = >{
this.init(item,index) // Initialize the video instance
},1000)}else{
this.dom.length=0}})},Copy the code
🫀 mouseenter and mouseleave
When using the V-for loop, mouseEnter and mouseleave are added to the parent element.
<div class="card" v-for="(item,index) in videoList" :key="index" >
<div style="width:100%; height:200px"
@mouseenter="startPlay(item,index)"
@mouseleave="move(item,index)">
<div
:ref="`img${index}`"
style="width:100%; height:200px; background-size: cover;"
:style="{'background-image':`url(${item.spsltlj+'/'+item.spslt}) `}">
</div>
<div style="display:none; overflow:hidden" :ref="`video${index}`">
</div>
</div>
<div class="title">
{{item.spmc}}
</div>
</div>
Copy the code
🎯 summary
The above is a simple demo of watermelon video, more powerful functions can be consulted on the official website, such as bullet screen, painting in painting, and so on are used, not only can be used in THE PC side, but also can be used in the mobile side.