H5 comes with player
Advantage
- Out of the box, support full screen and other functions
problem
The video can be played normally on the PC, but there are many problems when using the video tag on the mobile. You can refer to H5-Video can do things & existing pits
1. Video UI is inconsistent in different environments
2. Differences in API implementation and support in various environments:
See what the hell is this bunch of configurations below? ( References in this section )
<video
src="video.mp4"
controls
poster="images.jpg"
preload="auto"
webkit-playsinline="true"
playsinline="true"
x-webkit-airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
style="object-fit:fill">
</video>
different environments, we must do some configuration that meets its requirements, hoping to achieve the purpose we want as much as possible.
- But what I have to say is that the controls, posters, and autoplay in the standard API may not be effective.
- autoplay is not allowed on mobile browsers. , you can try whether autoplay is supported under mute
- The above-mentioned scheme of setting different media sources through source may not be recognized by some browsers.
For example, the scene where the monitoring data is loaded and the video data is obtained,
canplay
andcanplaythrough
have different levels of support on devices of different system versions. Generally, we will useonloadedmetadata
with good compatibility to get theduration
video.3. Inconsistency in event interaction behavior
- For example, ios part of the environment monitors
canplay
andcanplaythrough
(whether enough data is buffered for smooth playback), when will not be triggered, even ifpreload="auto"
is useless, but under the chrome debugger of pc and under android, It will be triggered during the loading phase, and will only be triggered after ios needs to be played. - some environments, the video will have a short black screen from the beginning to show the picture. (the time to process the video source data). To avoid this black screen, you can add a floating layer on the video or set the container background and hide the video before playing. , And then monitor related events, start playing or switch to the Video interface when it thinks there is a picture.
- In some environments, when you not set the poster on 161304c4a9070d, you will also try to load the poster, resulting in a black screen during the period of playing.
4. Media format support cannot be guaranteed
The overall support of MP4 is better, M3U8 is better in the high-version mobile environment, and there are a large number of flv playback requirements in the media-on-demand live broadcast. Native Video does not support it.
Handwriting mobile player
Target
- Cover
- Play/pause/replay
- Drag the scroll bar to adjust the progress
- Full screen and non-full screen
- Custom buttons such as share
accomplish
The first step: H5 adaptation template
<video
:src="videoSrc"
:poster="defaultPoster"
preload="auto"
@click.stop.prevent="handleVideoClick"
class="video__content"
playsinline="true"
x5-playsinline="true"
webkit-playsinline="true"
x-webkit-airplay="allow"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
></video>
preload
: The attribute specifies that the video is loaded after the page is loaded.controls
: The default will befalse
, we will implement the control bar control later.webkit-playsinline
,x5-playsinline
andplaysinline
: When the video is played, it will be played locally without departing from the document stream.x5-video-player-type
: Enable the H5 player in the same layer, that is, when the video is full screen, the div can be presented on the video layer, which is also a unique attribute of the WeChat Android versionx5-video-orientation
: Declare the directions supported by the player:landscape
horizontal screen,portraint
vertical screenx5-video-player-fullscreen
: Full-screen settings:true
supports full-screen playback, andfalse
does not support full-screen playback.object-fill
:fill
(will be forced to fill the player, the video ratio may be changed)/contain
(the video is played according to the ratio, and the width and height cannot fill the player at the same time)/...
Step 2: poster
Principle: Put a div container on top of the video and let this container fill the video component. Load the picture by setting background-image
<template>
<div
class="video-poster"
:style="style"
>
</div>
</template>
<script lang="ts">
import {
Vue, Prop, Component
} from 'vue-property-decorator';
@Component({})
export default class extends Vue {
@Prop()
public videoPoster?: string;
get style() {
return `background-image:url(${this.videoPoster})`;
}
}
</script>
<style lang="scss" scoped>
.video-poster{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 3; // 显示在video组件最上层
background-repeat: no-repeat;
background-size: 100% 100%; // 100%填充
background-position: 50%;// 居中放置
}
</style>
Step 3: Realize the progress control of the scroll bar
Support click the progress bar to adjust the progress and drag the dot to adjust the progress: place a scroll bar container, and put an actual progress area and a dot element in it.
currentTime determines the progress of the progress
活动的进度条长度 / 进度条总长度 = currentTime / duration
By passing different currentTime progress can be achieved in different display .
On this basis, a full-screen progress bar and a non-full-screen progress bar containing actions such as play/pause can be encapsulated.
There are two options for progress bar advancement:
The length of the activity progress bar is 100%. Initially, the activity progress bar is shifted to the left by 100%, and the setting beyond the container is
hidden
. Through the calculated distance, usetranslateX
control the movement.- Advantages: moving forward very smoothly
- Disadvantages: the position needs to be recalculated when switching between horizontal and vertical screens
Control the progress by the length of the activity progress bar
0-100%
- Advantages: automatic adaptation of horizontal and vertical screen switching
- Disadvantages: There is flickering when moving forward, the worse the performance, the more obvious.
The comparison found that flickering was acceptable when moving forward, and the second scheme was used.
// active controls 样式
public getWindowActiveMoveStyle(): Object {
const percent = this.currentTime / this.duration;
return {
'width':`${Math.round(percent * 10000) / 100}%`,
'background-color':`${this.activeControlBarColor}`
};
}
Click on the progress bar, converted to currentTime
// 点击进度条,换算成currentTime
private getTouchedTime(e: TouchEvent): number {
const clientRects = this.windowProgressEl.getClientRects() || []; // IOS>=6
const touchedClientX = e.touches[0].clientX;
const touchedClientY = e.touches[0].clientY;
const { left = 1, top = 0, width = 0, height= 0 } = clientRects[0] || {};
/** 根据是否全屏,计算方式也有区别:主要是旋转之后一些属性值发生了变化 */
const unit = this.fullscreen ? height : width;
const touchedClientUnit = this.fullscreen ? touchedClientY : touchedClientX;
const positionUnit = this.fullscreen ? top : left;
return (touchedClientUnit - positionUnit) / unit * this.duration;
}
Step 4: Realize full-screen playback
Picture size setting after full screen:
video{ // object-fit: fill; 这个会填充满区域,有些问题 object-fit: contain }
In non-full screen, the playback screen size is limited by the outer container; how to make the screen full without being restricted by the outer container in full screen
z-index:100; width : 100vmax; height : 100vmin; transform-origin: top left; transform: rotate(90deg) translate(0,-100vmin); background-color: #000;
Need to pay attention to converting to currentTime after screen conversion
private getTouchedTime(e: TouchEvent): number {
...
/** 根据是否全屏,计算方式也有区别:主要是旋转之后一些属性值发生了变化 */
const unit = this.fullscreen ? height : width;
const touchedClientUnit = this.fullscreen ? touchedClientY : touchedClientX;
const positionUnit = this.fullscreen ? top : left;
return (touchedClientUnit - positionUnit) / unit * this.duration;
}
other
Global loading
this.videoRef.addEventListener('waiting', () => { this.isLoading = true; }, false);
Network disconnection processing
public mounted(){ // 网络状况处理 window.addEventListener('offline', this.handleNetwork, false); window.addEventListener('online', this.handleNetwork, false); } private handleNetwork() { if (navigator.onLine) { this.isOnline = true; } else { this.isOnline = false; } }
Detail processing
Margin problem
- The position of the return button and the progress bar/play button should consider the curved screen
- The progress circle should be padding to prevent missing
Overall need for masking
- A mask is needed under loading to show that the loading animation turns
- Each icon on the player (white) and the progress bar need a mask to prevent the video content from being displayed when it is white
Reference materials:
- H5-Video problem: H5-Video can do things & existing pits
- H5video label settings: video H5 video label best practices
- Video format understanding: video screen to play those things
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。