How to monitor page closing or refreshing action -fengxianqi

In fact, this article could also be called how to monitor and upload users’ video duration. Recently, it is required to listen to the user’s action of playing a video and report the playing event. What needs to be reported is the duration of the user watching the video. There are several cases here. One is that the user clicks play, and the event video-. Ended is triggered, and the user’s watching time is reported. In the second case, the user clicks play and then leaves or refreshes the page. Before the user leaves, an event needs to be reported. This event mainly triggers the Window.onunload event.

The company’s technical solution is.M3U8 (HLS), which is currently only supported by Safari on PC, not Chrome, Firefox or most other mobile Android browsers. Therefore, using the native video TAB is not going to work, you have to find some plug-in or player. Finally, I chose DPlayer, which is a good open source player and easy to use. Back to business, reporting how long users watch videos.

Important update

Navigator-sendbeacon () is an API designed to deal with data embedders. However, please be aware of browser compatibility issues when using it. Currently (2018.06) mobile Android 5 + support. Ios version 11.3 or later is required. For details, see CanIUse. This article uses the new Image() method as a way to degrade sendBeacon() if it is not compatible. For more information, see navigator. SendBeacon () to report data.

The target

The viewing duration is reported when a user watches a video.

The preparatory work

    const dp = new DPlayer({
        container: document.getElementById('dplayer'),
        screenshot: true,
        video: {
            url: 'xx.m3u8',
            pic: 'xx.jpg'.type: 'customHls',
            customType: {
                'customHls': function(video, player) { const hls = new Hls(); hls.loadSource(video.src); hls.attachMedia(video); }}}}); // Whether to play the tag var isPlay =false;
    dp.on('play'.function () {
        console.log('player start');
        isPlay = true;
    });
Copy the code

In the first normal case, the user watches the entire video.

    dp.on('ended'.function () {
      console.log('player ended'); sendVideoPlayEvent(); // Event reporting method isPlay =false;
    });
Copy the code

In the second case, close the browser or refresh the page

When the user closes the page or refreshes the browser, the ONUnload event is triggered, and the time between the user starting to watch the video and leaving the page is how long the user is watching the video.

    window.onunload = function () {
      sendVideoPlayEvent();
      isPlay = false;
      console.log('onunload');
    };
Copy the code

Pit point

After testing, it is found that sendVideoPlayEvent will be invalid if ajax is used in either post or GET mode. The reason might be that the page closes too fast for Ajax to perform. After looking at a number of solutions, it turned out that a clever way to initiate the event was needed. Using the SRC attribute of the IMG tag, when img is inserted into the body, a request is made to fetch the resource, and the server can process the route. Finally, this method works and successfully reports the event at onunload.

    function sendVideoPlayEvent() {
      if (isPlay) {
        var videoId = getQueryString('videoId'); var duration = dp.video.currentTime; Var img = new Image(); img.style.display ='none'; img.src = `/api/video/play? duration=${duration}&videoId=${videoId}`; / / the server processing interface document. The body. The appendChild (img); }}function getQueryString(name) {
        var reg = new RegExp("(^ | &)" + name + "= (/ ^ & *) (& | $)"."i");
        var r = window.location.search.substr(1).match(reg);
        if(r ! = null)return unescape(r[2]); return null;
    }
Copy the code

conclusion

  1. Later on, the SRC of script tag should also be implemented, without validation.
  2. Pit is always a lot, more thinking…
  3. The idea is a little limited, there should be other solutions, welcome suggestions.