uni-app develops a small video application

I. Review of the Previous Situation

uni-app develops a small video application (1)

In the last article, we have implemented the home navigation bar component, the tabBar navigation bar component at the bottom, the video list component in the middle, and the video playback component in the video list component. After the rendering of the incoming video list, we have been able to slide up and down for video switchover and broadcast. Then we will finish the rest part of the home page, the left information bar component and the right icons bar. Components, and improve the video switching animation, playback control and other functions.

2. Create the left information bar component

The information bar component on the left side is mainly divided into three parts: author name, video title name and music name. This information bar on the left is associated with the currently playing video, so it should be rendered together with the information bar component on the left when looping the video list, so the information bar component on the left should be added to <swiper-item>.

// components/list-left.vue

<template>
    <view class="list-left">
        <view class="author">
            @Zhu Xiao Han
        </view>
        <view class="title">
            //Mom, I met my old classmate, fate! @ My father-in-law said car @ jitter little assistant
        </view>
        <view class="music-box"> <!--The music-box Mainly for the purpose of music Content scrolls beyond music-box Extended parts can be hidden after scope-->
            <view class="music">
                @The Original Voice of Zhu Xiaohao's Creation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  @The Original Voice of Zhu Xiaohao's Creation
            </view>
        </view>
    </view>
</template>
<style scoped>
    .list-left{
        width: 70%;
        height: 120px;
        color: white;
    }
    .author {
        height: 35px;
        line-height: 35px;
        font-size: 17px;
    }
    .title {
        width: 100%;
        line-height: 25px;
        font-size: 12px;
        word-wrap: break-word;
        color: #FFFAF0;
    }
    .music-box {
        overflow: hidden; <!--Exceeding partial hiding when scrolling-->
        width: 70%;
    }
    .music {
        width: 200%;
        height: 35px;
        line-height: 35px;
        font-size: 12px;
        animation: scroll-x 5s linear 0.2s infinite; <!--Applied animation-->
    }
    @keyframes scroll-x{ <!--Add text level scroll animation-->
        0% {
            transform: translate3d(80%, 0, 0); <!--80%Position appears, then scrolls to the left-->
        }
        100% {
            transform: translate3d(-80%, 0, 0); <!--Arrive at the end of the animation-80%position-->
        }
    }
</style>

// components/video-list.vue

<template>
    <view class="video-list">
        <view class="swiper-box">
            <swiper class="swiper" :vertical="true">
                <swiper-item v-for="(item,index) in videos" :key="index">
                    <view class="swiper-item">
                        <video-player                         
                             :video="item"                        
                            :index="index">
                        </video-player>
                    </view>
                    <view class="left-box"> <!--Place the left information bar component<swiper-item>Rendered with Video-->
                        <list-left></list-left>
                    </view>
                </swiper-item>
            </swiper>
        </view>
    </view>
</template>

<style>
.left-box { <!--Add absolute positioning and settings to the list components on the left z-index To display above the video-->
        position: absolute;
        bottom: 50px;
        left: 10px;
        z-index: 20; 
}
</style>

Create right icon bar components

The right icon bar components are mainly divided into: head Icon (head set border-radius), iconfont icon, comment icon (iconfont icon), iconfont icon, music Icon (picture set border-radius), the right icon bar components set a fixed width, and then let various icons in turn, such as:

// components/list-right.vue

<template>
    <view class="list-right">
        <view class="author-img">
            <img class="img" src="../static/zxh.jpg"/>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-xin"></view>
            <view class="count">72.2w</view>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-pinglun1"></view>
            <view class="count">1.8w</view>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-arrow-"></view>
            <view class="count">6645</view>
        </view>
        <view class="music-img">
            <img class="img" src="../static/music.jpg"/>
        </view>
    </view>
</template>

<style scoped>
    .list-right {
        width: 60px;
    }
    .author-img {
        width: 60px;
        text-align: center;
    }
    .img {
        width: 50px;
        height: 50px;
        border-radius: 50%;
    }
    .author-img img{
        border: 2px solid #FFFFFF;
    }
    .right-box {
        margin: 20px auto;
        color: white;
        text-align: center;
        font-size: 12px;
    }
    .icon {
        font-size: 40px;
    }
    .music-img {
        width: 60px;
        height: 51px;
        text-align: center;
        margin-top: 20px;
        animation: around 1.5s linear 0.2s infinite; <!--Using animation-->
    }
    @keyframes around { <!--Add 360 Circle Rotation Animation-->
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
</style>

4. Add the corresponding event to the icon component on the right

When you click on the plus icon at the bottom of the head image, you can pay attention to the user, that is, hide the plus icon, and the color switch of the collection love icon. When you click on the collection love icon, the love icon turns red, and then click on the collection love icon again, the love icon turns white. Here, only the change of color is handled, and the specific background interaction is not handled for the time being.

// Add a plus sign icon under the head icon by absolute positioning and locate it at the bottom of the head icon.

<view class="author-img">
    <img class="img" src="../static/zxh.jpg"/>
    <view class="follow iconfont icon-jiahao" v-show="showFollow" @click="hideFollow"><!--Add a plus sign Icon and listen hideFollow Event-->
    </view>
</view>

<view class="right-box">
    <view class="icon iconfont icon-xin" :class="{fav: isFav}" @click="changeColor"></view><!--Listen to Switch Collect Love Icon Colors-->
    <view class="count">72.2w</view>
</view>

<script>
    export default {
        data() {
            return {
                showFollow: true,
                isFav: false
            }
        },
        methods: {
            hideFollow() { // Hide attention to the plus sign Icon
                this.showFollow = false;
            },
            changeColor() {
                this.isFav = !this.isFav; // Switching Collection Love Colors
            }
        }
    }
</script>
<style scoped>
.follow {
        color: white;
        position: absolute;
        width: 18px;
        height: 18px;
        line-height: 18px;
        background: red;
        border-radius: 50%;
        text-align: center;
        left: 23px;
        bottom: -5px;
        font-weight: bold;
}
.fav {
        color:red;
}
</style>

5. Implementing Sliding Play Function

The so-called sliding playback, that is, when sliding up, pause the current playing video and play the next video, when sliding down, pause the current playing video, play the last video, and the most critical is how to judge whether sliding up or down. The < swiper > component provides us with a change event that we can listen for and slide to the page after the sliding is completed, that is, the serial number of < swiper-item > (starting from 0), and then compare with the current page before the sliding to see whether it is up or down.
After judging whether it is up or down, we need to deal with it correctly. We need to be able to get each video player component, and then call the relevant methods on the video player component to control the playback. This involves how the parent component calls the methods on the child component. If the parent component wants to call the methods on the child component, the key is that the parent component wants to call the methods on the child component. We can get the sub-component object by ref, because each video playback component is a sub-component of the video-list video list component, so we can add a ref="player" to each video-list video playback component to get the corresponding video playback component.

// components/video-list.vue

<swiper class="swiper" :vertical="true" @change="slider"> <!--Monitor change Event-->
    <swiper-item v-for="(item,index) in videos" :key="index">
        <view class="swiper-item">
            <video-player
                ref="players" <!--Add one for each video playback component ref Identification-->
                :video="item"                        
                :index="index">
            </video-player>
        </view>
    </swiper>
</swiper>
<script>
export default {
    data() {
        return {
            currentPage: 0 // Save the number of the current page
        }
    },
    methods: {
        slider(e) {
            const targetPage = e.detail.current;
            if (targetPage === this.currentPage + 1) {
                console.log("wipe up");
                this.$refs.players[this.currentPage + 1].playFromHead(); // Next start playing and start playing from scratch
                this.$refs.players[this.currentPage].pause(); // Current video pause
            } else if(targetPage === this.currentPage - 1) {
                console.log("Slide down");
                this.$refs.players[this.currentPage - 1].playFromHead(); // The last one started playing and started playing from scratch
                this.$refs.players[this.currentPage].pause(); // Current video pause
            }
                this.currentPage = targetPage;
        }
    }
}
</script>

It should be noted that this.$refs.players returns an array of instances of all playback components. We can obtain the corresponding video playback components through different indexes, and then control the corresponding playback. Next, we need to add a playback control method to each video playback component. We need to add an id to the < video > component, and then pass through it. This id can create a video context, which can call play(), pause(), seek() and other related methods to control playback.

// components/video-player.vue

<template>
    <view class="video-player">
        <video class="video"
               id="myVideo" <!--to video Add a component id´╝îIn order to obtain video Context object-->
               :src= "video.src" 
               :controls="false"
               :loop="true">
        </video>
    </view>
</template>
<script>
export default {
    onReady() {
            this.videoContext = uni.createVideoContext("myVideo", this); // Get the video context object
    },
    methods: {
        play() {
            this.videoContext.play();
        },
        pause() {
            this.videoContext.pause();
        },
        playFromHead() { // Jump to the start position and play
            this.videoContext.seek(0);
            this.play();
        }
    }
}
</script>

6. Implementing click-play pause switch and double-click attention user function

To achieve click-on video playback component, video can be played and pause switching, then we need to add an isPlay attribute to the video playback component to indicate whether the video is playing, if it is playing, then click-pause, if it is not playing, then click-play, at the same time, because uni-app does not support vue dblclick events, so we need to add an isPlay attribute to the video playback component. To judge clicks and double-clicks, we need to define a variable to record the number of user clicks. If the number of user clicks in 300 ms is greater than or equal to 2, then it is double-click, otherwise it is click, such as:

<template>
    <view class="video-player">
        <video class="video"
               id="myVideo"
               :src= "video.src" 
               :controls="false"
               :loop="true"
               @click="doClick"><!--Add to click Event switching for video playback and pause-->
        </video>
    </view>
</template>
<script>
    let timer = null; // Define a timer
    export default {
        data() {
            return {
                isPlay: false, // Whether the current video is playing by default is false
                clickCount: 0 // Record current user clicks, default is 0
            }
        },
        methods: {
            play() {
                this.videoContext.play();
                this.isPlay = true; // Enter the video playback status and set isPlay to true
            },
            pause() {
                this.videoContext.pause();
                this.isPlay = false; // Enter the video pause state and set isPlay to false
            },
            playFromHead() {
                this.videoContext.seek(0);
                this.play();
            },
            doClick() { // Switching between video playback and pause
                if (timer) {
                    clearTimeout(timer);
                }
                this.clickCount++; // Each click on the video playback component, click times plus 1
                timer = setTimeout(() => {
                    if (this.clickCount >=2 ) { // If the number of clicks in 300 ms is more than or equal to 2, it means double-click.
                        console.log("double-click");
                        this.$emit("follow"); // Send a follow event to the video-list parent (video list component) if you double-click
                    } else {
                        console.log("Single click");
                        if (this.isPlay) {
                            this.pause();
                        } else {
                            this.play();
                        }
                    }
                    this.clickCount = 0; // Reset clicks 0
                }, 300);
            }
        }
    }
</script>

When double-clicked, a follow event is sent to the video-list parent component (video list component). The video-list component listens to the follow event and then notifies the <list-right> component to call its method to make its love icon red. For example:

<template>
    <video-player
        @follow="follow">
    </video-player>
    <view class="right-box">
        <list-right ref="listRight"></list-right> <!--to list-right Component add ref Identification-->
    </view>
</template>
<script>
    export default {
        follow() {
            this.$refs.listRight[0].follow();
        }
    }
</script>

Implementing the First Automatic Video Playing Function

Previously, our video playback component received an index attribute, which is the index number corresponding to the current video. We can use this index number to determine whether the current video is the first, and then set the autoPlay of its video component to true to play automatically.

<template>
    <view class="video-player">
        <vide :autoplay="auto> <!--binding autoplay Property control whether to play automatically-->
        </video>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                auto: false // Whether to Play Automatically
            }
        },
        methods: {
            autoPlay() {
                if (this.index === 0) {
                    this.auto = true;
                }
            }
        },
        created() {
            this.autoPlay();
        }
    }
</script>

So far, the home page has been completed.

Tags: Javascript Vue Attribute REST

Posted on Tue, 08 Oct 2019 07:09:46 -0700 by waqasahmed996