The following is their own step on the pit, hope to help you ~

1, X5 same layer player

The video element in mobile browsers is quite special. In the early days of both iOS and Android browsers, it was located at the top of the page and could not be covered. This has since been fixed on iOS, but remains the case on Android. X5 is Tencent’s WebKit-based rendering engine, which provides a special video element called the “same layer player” to solve the masking problem.

You can call the peer player by adding X5’s custom attribute x5-video-player-type to a normal video element.

<div class="player">
    <video id="video" class="video" controls="controls" playsinline x5-video-player-type="h5">
        <source src="video.mp4" />
    </video>
</div>
Copy the code

The video style of the same layer player is the same as the ios video player. Android’s native player (not the same player) has no control over whether it plays automatically or whether it plays full screen when clicked.

If you want android video to look the same as ios, you can use Tencent’sH5 same layer player access specification.

Playing within the same page is the standard video playing mode. Add x5-Video-player-type: H5-page attribute in the video label to control the playing within the same page, and display HTML elements at the top of the video.

Pit points note:

Using TBS peer player of X5, below TBS version 4.5.2 (this is obtained after testing more than 10 Android phones), a full-screen button that cannot be removed will appear at the upper right of the video, as shown in the figure:

To remove this button, use CSS to squeeze the video area out of the screen, and use object-opsition to position the video back to its normal position. The following video-player__main__tech is the video element:

&.x5-android { overflow: hidden; & { .video-player__main { padding-left: 200px; width: calc(100% + 200px); .video-player__main__tech { position: absolute; width: calc(100% - 200px) ! important; right: 0; object-position: calc(50% - 200px) 50% ! important; }}}}Copy the code

It must be noted that style adaptation is not required for X5 TBS version above 4.5.2, otherwise the video picture will be missing, so make a judgment before using:

isAndroidX5SupportInlinePlayer() { const ua = window.navigator.userAgent; const tbs = ua.match(/TBS\/([\d.]+)/); const x5 = { tbsWx: ua.match(/MicroMessenger/i) == 'micromessenger' && tbs && tbs[1] >= 36849, // tbsQQ: Browser.versions.QQ && isTBS && (isTBS[1]>= 36855) && (isTBS[1] <= 45200), // QQ built-in webView MQQBrowser: Ua. Match (/ MQQBrowser \ / (/ \ d +) /) && ua. The match (/ MQQBrowser \ / (/ \ d +) /) [1] > = 7.2, built-in browser / / qq or qq webview tbsX5: TBS && TBS[1] >= 36900&& (isTBS[1] <= 45200)// Third-party access to the TBS X5 kernel, such as Android. Note: Android QQ browser UA does not have TBS (Android QQ built-in WebView UA has TBS)}; return ( (ua.indexOf('Android') > -1 || ua.indexOf('Linux') > -1) && (x5.tbsWx || x5.tbsQQ || x5.MQQBrowser || x5.tbsX5) ); },Copy the code

2. Autoplay Automatically plays

The video TAB can be set to autoplay, just set autoplay on the TAB. However, setting autoplay can be a compatibility issue, and not on all models.

1. Ios gave mostly autoply to autoplay, but muted, i.e., no audio tracks, or a fraternal attribute.

2. On Android, only some phones can play automatically. And can not simulate automatic play, must have user behavior can trigger play.

Wechat auto play

Wechat auto play is too much pit T_T, the specific performance is as follows

1. When ios triggers the Play () method without user interaction, an error will be reported, resulting in the video cannot be loaded. Solutions:

document.addEventListener( "WeixinJSBridgeReady", () => { this.video.play(); }, false ); // Compatible with wechat auto playCopy the code

However, this method also has a problem, which is related to the injection timing of WeixinJSBridge. Sometimes it is fast and sometimes it is slow. Therefore, if the project is a single-page application like Vue, it needs to load additional JS to generate DOM elements in order to define the above method. As a result, the WeixinJSBridgeReady defined may not be triggered every time, so it may not be successful every time automatic playback.

2. In Android, if auto play is set, the video will play first (currentTime is not changed, the video is loading, so there is no playback progress), and the video will pause after loading. If the cover art is self-implemented instead of using video, it will give the user an abnormal performance (because the user experience is that the cover art disappears while the video is not playing). My solution:

  • Listen for pause events in the video
  • If currentTime of the video is false (0 or NaN), android and wechat, the cover image will be restored.
OnPause: function() {self.status = "pause "; self.isPlaying = false; if(! self.currentTime && ! Util. IsIOS () &&util. IsWeixin ()) {// The cover image will disappear before it is played. // So use this method to recover your cover image self.isplayed = false; }else{ self._fixShowControl(); }},Copy the code

3. In-line video playback

By default, playing video will play in full screen. If you want the video to play in part, you can set x5-playsinline

Pit points note:

X5-video-player-fullscree =true If x5-video-player-fullscree=true if x5-video-player-fullscree=true if x5-video-player-fullscree=true if x5-video-player-fullscree=true if x5-video-player-fullscree=true if x5-video-player-fullscree=true if x5-video-player-fullscree=true Solution: Add the video full screen operation in the event that clicks play video

4. The size of the video after full screen playing

This is only true for android players playing in full screen. After full-screen playback on the same layer player, the background color of the video will turn black, and then the video will only be centered in the middle, with the size of the original video set, rather than full screen.

The result is shown below.

1. The solution I adopted for the first time is that when the video is in full screen, the onresize method will be triggered. In this method, the video size is set to the width and height of the screen forcibly:

let video = this.$refs.video; This.myplayer. on('play',() => {console.log('play') window.onresize = function () {this.myplayer. on('play',() => {console.log('play') window.onresize = function () { document.querySelector('.video-container').style.width = window.innerWidth + "px"; document.querySelector('.video-container').style.height = document.documentElement.clientHeight + "px"; } }) this.myPlayer.on('pause',() => { console.log('pause') window.onresize = function () { document.querySelector('.video-container').style.width = "270px"; document.querySelector('.video-container').style.height = "170px"; }})Copy the code

But this way, because the size of the entire video is set directly to the width and height of the current screen, the test reflects that the video is stretched out of shape because the size is not proportional.

2. Therefore, the following schemes are adopted. VideoHeight () and videoWidth() get the height and width of the original video, respectively, and then calculate the ratio to the width and height of the screen.

if (MJSSDK.UA.android) { this.myPlayer.on('play', () => { // console.log('play'); window.onresize = () => { // console.log('onresize-play'); this.isfull = true; let vheight = this.myPlayer.videoHeight(); let vweight = this.myPlayer.videoWidth(); let clientHeight = document.documentElement.clientHeight; document.querySelector('.video-container').style.width = (clientHeight * vweight) / vheight + 'px'; document.querySelector('.video-container').style.height = clientHeight + 'px'; document.querySelector('#my-video').style.backgroundColor = 'black'; }; }); this.myPlayer.on('pause', () => { // console.log('pause'); window.onresize = () => { // console.log('onresize-pause'); this.isfull = false; Document. querySelector('.video-container').style.width = '270px'; document.querySelector('.video-container').style.height = '170px'; }; }); }},Copy the code

5. White edges appear after the video is in full screen

This is a weird issue and only happens on some Android devices. As shown in figure:

After checking, the white edge is the color of the page, which is the full screen of the player of the same layer. Rotate the page and enlarge the area like this. Solution: Set the background color to black when the page is in full screen, and change it back when the page is in full screen.

6. Full-screen method call problem

Since the control bar of the video player is implemented by itself, you need to implement your own full-screen method.

1. Native full screen

Native full screen usually uses this method:

        if (video.requestFullscreen) {
            video.requestFullscreen();
        } else if (video.mozRequestFullScreen) {
            video.mozRequestFullScreen();
        } else if (video.webkitRequestFullscreen) {
            video.webkitRequestFullscreen();
        } else if (video.webkitSupportsFullscreen) {
            video.webkitEnterFullscreen();
        } else if (video.msRequestFullscreen) {
            video.msRequestFullscreen();
        } else {
            this.addClass(el, "video-player--is-cssfullscreen");
        }
Copy the code

Later, I looked at the source of VideoJS, and found that screenfull.js can be used to directly achieve full screen, very convenient.

import screenfull from "screenfull";
if (screenfull.isEnabled) {
    screenfull.request(video);
}
Copy the code

However, after debugging on ios, screenFull.request (video) can not achieve full screen, and can not listen to get full screen change events. Only webkitEnterFullscreen() works in full screen on ios

Therefore, to be compatible with ios:

                if (util.isIOS()) {
                    document.getElementById(this.vId).webkitEnterFullscreen();
                    return;
                }
Copy the code

2. Pseudo full screen

Pseudo full screen here refers to the style full screen implemented through CSS, which allows custom HTML elements to be overlaid on the video.

1, vertical version full screen

For full screen, add the following styles to the video:

.video-player--is-cssfullscreen { position: fixed ! important; left: 0 ! important; top: 0 ! important; width: 100% ! important; height: 100% ! important; z-index: $z-index-video ! important; }Copy the code

2, horizontal version full screen

When clicking full screen, first rotate the outermost parent container of the video element by 90 degrees and set it to Fixed to fix the window. To center the video, set left to 50% and top to half the width of the current document, which I used to be -375px.

.cross-screen {
        position: fixed;
        top: -375px;
        left: 50%;
        background: #000;
        transform-origin: 0;
        transform: rotate(90deg) translate3d(0, 0, 0);
    }
Copy the code

The width of the parent element above the video is set to the height of the window and the height is set to the width of the current window:

        this.crossScreenStyle = {
            width: window.innerHeight + "px",
            height: window.innerWidth + "px",
        };
Copy the code

Pit points note:

If the position: Fixed and Transform attributes are set at the same time, the Z-index level may behave incorrectly, and elements with higher levels are overwritten by elements with lower levels. Solution: Add an additional transform: translateZ(100px) attribute to the high level element to raise the element up

7. The video tag is hijacked by the browser

Phenomenon:

Forces the Controls bar to appear

Forced to full screen

Mandatory picture-in-picture

Force float player and float bug

Wait…

The above phenomenon still occurs even when using x5 player.

I am currently in vivo in a mobile phone reproduction.

The solution

The browser vendor adds a domain name whitelist. For example, the uc ios whitelist contains *.v.qq.com *.taobao.com

8. Dynamic insertion of video labels

In order to improve page rendering performance, dynamic insertion of the video label will be considered, such as inserting the video label into the corresponding container after clicking play.

However, if the X5 player is enabled, dynamically inserted videos can be hijacked by browsers.

The solution

1. You can use the solution in Point 7

2. If the x5 kernel is used, dynamic insertion is not used