Compatibility problems such as video peer level, disabling progress bar, etc

Posted by eyedol on Wed, 19 Jan 2022 15:53:53 +0100

Based on video JS usage problem

These problems are encountered in my project. My project is to set problem points for video. Users can't click the progress bar to fast forward when watching. They can fast forward what they have seen. When they encounter problem points, they will pause and pop up questions. If they answer correctly, they can continue to watch. If they answer incorrectly, they will return to the position of the previous question to watch again, and the user's viewing position shall be recorded, The next time you come in, you will be prompted whether you want to jump to the last viewing position, including the pc end and the mobile web end. At present, the biggest problem is to test the compatibility of the mobile end. It took a lot of time to summarize. It is generally OK. The browser compatibility effect is still not fully compatible, because there is no solution to the video tag. Later, I also try to change the plug-in, such as the watermelon player, but after testing, the hierarchy problem has not been solved. I gave up. The following summary is less. If there is a problem, communicate more.

The following question is based on video Problems encountered in JS development

1. Disable progress bar

Requirements: users are not allowed to click or drag the progress bar fast forward if they have not seen it. The viewed part can be dragged or fast forward

pc end:

Normal page: timer + mouse click event (one more event is to prevent the user from clicking the problematic point all the time)

Simulator: only use the timer (the simulator will unbind the mouse event and the pc will rebind when the monitor window judges)

Mobile terminal:

Just a timer

// 1. Binding event processing
    // Click progress bar event - bind event
   // Bind on initialization 
        window.owner.isBind = true;
        document
          .getElementsByClassName("vjs-progress-control")[0]
          .addEventListener("mousedown", window.owner.dot);

        document
          .getElementsByClassName("vjs-progress-holder")[0]
          .addEventListener("mousedown", window.owner.dot);
    
    dot() {
      window.owner.isSeek = true;// The sign jumps
      window.owner.oldTime = this.player.getCache().currentTime; // Get the time of the last click (the time of the position before the click jump will be cached by default)
    },
 
      // Click the listening jump corresponding to the event. This event is executed every 250ms
            that.on("timeupdate", function() {
          // If you click the progress bar to jump to the problem point and are not from the mobile terminal simulator, this is prohibited
          if (
            (that.currentTime() > window.owner.maxTime) &&
            window.owner.isSeek &&
            !window.owner.isMobile
          ) {
            that.currentTime(window.owner.oldTime); // Back to the previous point
          } else {
          }
        }); 
        
// 2. Timer
     // Turn on time -- when the playback event is turned on
      that.on("play", function() {
          window.owner.isSeek = false;
          // Enable progress bar disable timer: clear before starting. Make sure you only drive one at a time
          clearInterval(window.owner.timeId1);
          window.owner.timeId1 = setInterval(window.owner.timer, 300);
        });

     // Timer to judge whether the user is fast forward or dragging the progress bar
    timer() {
      let curTime = this.player.currentTime(); // current time 
      var apartTime = curTime - window.owner.oldTime; // The difference between the current time and the last saved time is greater than 2, which means that the user clicked the progress bar fast forward
      // If it is greater than the maximum recording time and is not a teacher preview, jump back to the original learning position
      if (
        apartTime > 2 &&
        curTime > window.owner.maxTime &&
        !window.owner.isTeacherPreview
      ) {
        this.player.currentTime(window.owner.oldTime); // Reset back to the position before clicking
      } else {
        window.owner.oldTime = curTime; // Record time
        if (curTime > window.owner.maxTime) {
          window.owner.maxTime = curTime; // Maximum recording time
        }
      }
    },

// mounted add listening window changes
window.onresize = function() {
      window.owner.isMobiles(); // Monitor the change of the window and judge whether the user uses the debugging simulator to open the page on the pc
    };
    
   // Judge whether the user has switched the browser's simulator to run. If yes, unbind the event and only use the timer
    isMobiles() {
      if (
        window.navigator.userAgent.match(
          /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
        )
      ) {
        window.owner.isMobile = true;
        if (window.owner.vData.isStudyDown != 1) {
          window.owner.isBind = false;
          document
            .getElementsByClassName("vjs-progress-control")[0]
            .removeEventListener("mousedown", window.owner.dot);

          document
            .getElementsByClassName("vjs-progress-holder")[0]
            .removeEventListener("mousedown", window.owner.dot);
        }
        console.log("Mobile terminal simulator");
        return true; // Mobile terminal
      } else {
        window.owner.isMobile = false;
        if (window.owner.vData.isStudyDown != 1 && !window.owner.isBind) {
          document
            .getElementsByClassName("vjs-progress-control")[0]
            .addEventListener("mousedown", window.owner.dot);

          document
            .getElementsByClassName("vjs-progress-holder")[0]
            .addEventListener("mousedown", window.owner.dot);
        }
        console.log("pc end");
        return false; // PC end
      }
    }

2. Jump play problem

pc end:

That's it

this.player.currentTime(time); // Jump

Mobile terminal:

The above method directly jumps on the mobile terminal. The browser support on the mobile terminal is inconsistent. qq and wechat can, but uc/qq browser can't. We need to play it first. It's OK to jump after initializing the video

solve:

Set a flag bit to monitor the jump in timeupdate, and play the video before the jump

    // Jump play
    handleSkip() {
        clearInterval(window.owner.timeId1); // Clear the timer first
        window.owner.oldTime = Number.parseInt(this.vData.midVideoStudyLength);
       // this.player.currentTime(
         // Number.parseInt(this.vData.midVideoStudyLength)
        //); //  Jump directly. Some mobile browsers can't jump, such as qq browser
        this.player.play(); // play
        this.skipFlag = true; // Set jump
        this.showSkipToast = false;
        //   SetTimeout (() = > {/ / the timer is not recommended. The jump will jam
        //   player.currentTime(ctime)
        // }, 500)
    },
        
        // Monitoring jump and record saving
           that.on("timeupdate", function() {
          let time = window.owner.getCurrentTime();
          localforage.setItem("videoLearnerTime", {
            midTime: time,
            maxTime: window.owner.maxTime
          }); // Keep records
          // Jump
          if (window.owner.skipFlag) {
            that.currentTime(
              Number.parseInt(window.owner.vData.midVideoStudyLength)
            );
            window.owner.skipFlag = false;// Jump to false
          }
        });

For the inaccurate jump time, for example, jumping to 2.5s will directly jump to 3s, which involves the problem of frame spacing. You can baidu this knowledge.

3. Video record preservation

pc and single page mobile terminal:

Call the save api when the component is destroyed, but there is another case, that is, save when the page is refreshed and closed. At this time, my method is to listen to the page unloading event

1.Page destruction
beforeDestroy() {
    window.onbeforeunload = null;
    // Clear timer
    this.showSkipToast = false;
    this.studyAll = false;
    clearTimeout(window.owner.timeId);
    clearInterval(window.owner.timeId1);
    let time = this.getCurrentTime();
    if (time > 0) { // Save record save current time and maximum viewing time maxTime
      this.markVideoStudyLength(parseInt(time));
    }

    if (this.player) {
      this.player.dispose(); // //Destroy the video instance to avoid that the node does not exist but flash is always executing and re entering the page. The video is not declared again
    }
  },
      
 2.
// Page unloading and saving records -- for the pc terminal, the mobile terminal has a bad experience
    window.onbeforeunload = function(e) {
      e = e || window.event;
      // Compatible with versions before IE8 and Firefox 4
      if (e) {
        e.returnValue = "Close prompt";
      }
      window.owner.isClose = true;
      let time = window.owner.getCurrentTime();

      if (time > 0) {
        window.owner.markVideoStudyLength(parseInt(time));
      }
      // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
      return "Close prompt";
    };

Multi page mobile terminal:

In the form of multiple pages, the component does not call the destroy function, so it cannot be saved during destruction, and if multiple pages jump to a page, the page will be refreshed again, so you can use localstorage to save records and save them in timeupdate, Then read the value of localstorage in the parent component life cycle function and save it (depending on the specific situation, where to save it is only provided here, because some people call components differently)

4.video level issues

The video tag will be hijacked in some browsers and cannot be overwritten. qq, wechat, edge and safari do not have this problem. uc/qq browsers (full screen) and other parts will have this problem

This situation will affect the pop-up problem pop-up box during video playback, which is covered

Solution: this idea can only be roughly solved, because it only fits qq, wechat, edge and safari. There's really no other way

  1. Add properties, set the browser that supports x-h5 kernel to play video in the same layer

  2. By hiding the element tag, the parent tag display:none of the video tag is set when the pop-up frame is encountered. The pop-up frame is cancelled and then set back to block

     1. 
       <div
            class="video-player-container"
            ref="videoContainer"
            v-show="videoShow"
          >
           <video
              ref="videoPlayer"
              id="video_palyer"
              class="video-js vjs-default-skin vjs-big-play-centered "
              x5-video-player-type="h5" // Same layer playback
              webkit-playsinline="true"
              playsinline="true" // In line, not out of document flow
              x-webkit-airplay="allow"
              x5-video-orientation="portrait" // Vertical display
              x5-video-player-fullscreen="true" 
            ></video>
        </div>
    2.
    
    

4.css some style settings

Style settings

// Pause display of large buttons
::v-deep .vjs-paused .vjs-big-play-button,
::v-deep .vjs-paused.vjs-has-started .vjs-big-play-button {
  display: block;
  font-size: 3.5em;
}
// Forward play, display the played duration
::v-deep .video-js .vjs-time-control {
  display: block;
}
::v-deep .video-js .vjs-remaining-time {
  display: none;
}
::v-deep .vjs-control-bar {
  font-size: 14px;
}
//5. Black edge will appear during pause
 to video Label plus style=" outline: none"

5. Some event execution sequences

Some event trigger sequences:

timeupdate is triggered whenever the video is played and the playback time is changed. It is executed every 205ms

1. Normal play

play - timeupdate - pause

2. During normal playback, click the progress bar to fast forward to another position (fast rewind is the same process)

Playback time change –

Pause – pause
Looking for -- seeking
Playback time change – timeupdate
Found – found
Playback time change – timeupdate
Playback time change – timeupdate
Start playing: – play

console.log printing process:
Playback time change: 36.856077
v2.vue?9818:48 pause 36.856077
v2.vue?9818:55 looking for: 36.856077
v2.vue?9818:63 playback time change: 36.856077
v2.vue?9818:59 Search completed: 36.856077
v2.vue?9818:63 playback time change: 36.856077
v2.vue?9818:63 playback time change: 36.856077
v2.vue?9818:51 start playing: Play: 36.856077

3. Click the progress bar fast forward when pausing (pause at the beginning and play at the end are missing)

Looking for
Playback time change
Search complete
Playback time change
Playback time change

4. Drag the progress bar (almost, but the addressing process will be triggered multiple times)

Pause – pause
Searching -- seeking (these three will trigger multiple times)
Playback time change – timeupdate
Found – found
Playback time change – timeupdate
Playback time change – timeupdate
Start playing: – play

end:
It's probably a little summary. The notes can't be done very well. You can communicate with me if you have questions

Topics: Javascript Web Development Vue