Demand background: in the small program page to insert GIF dynamic picture, but GIF picture is generally large, turn to the mode of automatic playback video to simulate the effect of GIF picture, rich page display. Automatic playback video, no control bar, no sound, automatic loop playback.

Technical difficulties: When there are multiple videos (no more than 3 videos are recommended) on the same page of wechat mini program, there will be delay or even flash back. Developers.weixin.qq.com/community/d…

Solution: refer to the small program community discussion plan, when the video does not appear in the screen visible area, use the picture to occupy, appear on the screen, replace the picture with the video, and automatically play.

Note: The video tag uses wx:if, and the image tag uses the visibility style.

<view class="container" style="width: {{videoWidth}}rpx; height: {{videoHeight}}rpx">
  <image class="image" style="visibility: {{play ? 'hidden' : 'visible'}};" id="image_{{videoId}}" src="{{poster}}" />
  <video class="video" wx:if="{{play}}" id="video_{{videoId}}" controls="{{controls}}" object-fit='contain' show-center-play-btn="{{showCenterPlayBtn}}" enable-progress-gesture="{{enableProgressGesture}}" direction="{{direction}}" enable-play-gesture="{{enablePlayGesture}}" muted="{{muted}}" loop="{{loop}}" src="{{videoUrl}}" />
</view>
Copy the code
.container {
    position: relative;
    width: 100%;
    height: 100%;
}
.image {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    width: 100%;
    height: 100%;
}
.video {
    width: 100%;
    height: 100%;
}
Copy the code
Component({
    properties: {
        // Video width
        videoWidth: {
            type: Number.value: 0,},// Video height
        videoHeight: {
            type: Number.value: 0,},// Video poster/cover art
        poster: {
            type: String.value: ' ',},// Video link
        videoUrl: {
            type: String.value: ' ',},// Whether to display the progress bar
        controls: {
            type: Boolean.value: false,},// Whether to display the middle play button
        showCenterPlayBtn: {
            type: Boolean.value: false,},// Whether to mute
        muted: {
            type: Boolean.value: true,},// Whether to display the mute button
        showMuteBtn: {
            type: Boolean.value: true,},// Whether to enable gesture control progress
        enableProgressGesture: {
            type: Boolean.value: false,},// Whether to enable gesture control playback
        enablePlayGesture: {
            type: Boolean.value: false,},/ / direction
        direction: {
            type: Number.value: 0,},// Specify the start time, in seconds
        showPlayTime: {
            type: Number.value: 0,},// Video id (unique identifier)
        videoId: {
            type: String.value: ' ',},// Whether to play
        play: {
            type: Boolean.value: false,},// Whether to loop
        loop: {
            type: Boolean.value: true,}},data: {
        paly: false.// Whether to play
        context: null.// Create the video instance object
    },
    lifetimes: {
        attached() {
            this.videObserve(); }},methods: {
        // Listen for the video component to enter the viewable area
        videObserve() {
            this._observer = this.createIntersectionObserver({
                observeAll: true});this._observer.relativeToViewport().observe(`#image_The ${this.data.videoId}`.(res) = > {
                Res. intersectionRatio === 0 indicates disintersection
                if (res.intersectionRatio === 0) {
                    this.setData({
                        play: false}); }else {
                    const ctx = this.data.context || wx.createVideoContext(`video_The ${this.data.videoId}`.this);
                    if (ctx) {
                        this.setData(
                            {
                                context: ctx,
                                play: true,},() = > {
                                // The delay is added to wait until the WXML node is created and retrieved before playing, otherwise it may fail to play
                                setTimeout(() = > {
                                    ctx.play();
                                }, 400); }); }}}); ,}}});Copy the code

rendering


When the video enters the viewable area, the video is loaded and starts to play. When the video leaves the viewable area, play=false clears the video label, that is, the video is cleared.

Future optimization point


  1. Currently, a black screen appears when the video is first rendered. Later see if you can change it to white (white is better than black), also depends on the small program video support.
  2. Currently, no more than 3 videos can be played simultaneously on a screen. If the width and height of the video are relatively small, there may be many videos on one screen, which may stall or flash back.