Now, playing video on the web has become more and more popular, but the online information is mixed, it is difficult to find their own want, today xiaobian on their own development experience, hand in hand from scratch – package a Vue video player components.

How could a skilled front end brick-remover be so obsessed with his own business? Look for wheels online first

After constant searching on the Internet, I finally chose the wheel of Video.js as my player. Okay, now that the wheel is found, at first glance, gee, it looks a little ugly. Don’t worry, I’ll make it nice again.

The introduction of video. Js

The installation

// Install the video.js plug-innpm install video.js -S 

// If you want to play the RTMP live stream, install the pluginnpm install videojs-flash -S
 Copy the code

Simply use plug-ins in components

template
<template>
  <div>
    <div data-vjs-player>
      <video ref="videoNode" class="video-js vjs-default-skin"> </video>    </div>
</template> Copy the code
script
import videojs from "video.js";
// Player Chinese, can not use.js fileimport videozhCN from "video.js/dist/lang/zh-CN.json";
// The style file must be addedimport "video.js/dist/video-js.css"; 
// If you want to play RTMP, you need to use flash NPM I videojs-flashimport "videojs-flash"; export default {  data() {  return {  player: null,  };  }, // Initialize the player mounted() { let options = {  autoplay: true, // Auto play language: "zh-CN".Controls: this. Controls, // Control bar preload: "auto", // automatic loading errorDisplay: true// Error display // fluid: true// Follow the size of the outer container, follow the width of the outer container width: "500px". height: "500px". // controlBar: false/ / set tofalseDo not render the control bar DOM element, just set controls tofalseIt doesn't show, but it exists // textTrackDisplay: false// Do not render subtitle related DOM userActions: {  hotkeys: true// Whether hotkeys are supported },  notSupportedMessage: "This video cannot be played, please try again later.". techOrder: ["h5"."flash"],// define the preferred order of the video.js technology sources: [  {  src: 'Video or Live address'. type: 'video/mp4'. //type: 'rtmp/flv'. }  ]  };  this.player = videojs(  this.$refs.videoNode,  options,  function onPlayerReady() { videojs.log(`Your player is ready! `); }  );  videojs.addLanguage("zh-CN", videozhCN);  },  beforeDestroy() {  if (this.player) {  this.player.dispose();  }  } } Copy the code

Such a simple video playback function is realized. Here are some common configuration items for Video.js:

Commonly used options
  • Autoplay: true/false Whether toplay automatically when the player is ready [default false]
  • Controls: True /false Whether you have a control bar (default true). If set to false, you can only control it through the API. This means there are no control buttons on the interface
  • Height: the height of the video container, a string or numeric unit pixel such as: height:300 or height: ‘300px’
  • Width: The width of the video container in string or numeric units of pixels
  • Loop: true/false Indicates whether to play the video loop after the video is played
  • Fraternal: true/false Indicates muted
  • Poster: Video images displayed before playback, which will be automatically removed after playback. Usually a URL is passed in
  • ‘auto’, ‘metadata’, ‘video length’, ‘size’, ‘none’ No data is preloaded until the user starts playing the video
Video.js specific options

By default, each option is undefined unless otherwise specified

aspectRatio

Type: string

Place the player in fluid mode and use this value when calculating the dynamic size of the player. This value should represent the ratio – two numbers separated by a colon (for example, “16:9” or “4:3”).

autoSetup

Types: Boolean

Prevents the player from running autoSetup for media elements with data-setup attributes.

Note: you must with videojs. Options. AutoSetup = falsevideojs source load at the same time global Settings to take effect.

fluid

Types: Boolean

Set to true, the video.js player will have smooth size. In other words, it will expand to fit its container.

In addition, this option is automatically set to true if the element has “vjS-fluid”.

inactivityTimeout

Type: number

Video.js indicates that the user interacts with the player through the “jS-user-active” and “jS-user-Inactive” classes and the “UserActive” events.

InactivityTimeout determines inactivity for many milliseconds before declaring the user idle is required. A value of 0 means that without inactivityTimeout, the user is never considered inactive.

language

Type: string, default: browser default or ‘en’

A language code that matches one of the available languages in the player. This sets up the initial language for the player, but it can always be changed.

Learn more about the language in video.js.

languages

Type: the Object

Customize the languages available in the player. The key of this object will be the language code, and the value will be an object with English keys and translated values.

Learn more about the language in video.js

Note: In general, this option is not required and it is best to pass the custom language to videojs.addLanguage() to all players!

nativeControlsForTouch

Types: Boolean

Explicitly set the default values for the associated technology options.

notSupportedMessage

Type: string

Allows you to override the default message displayed when video.js cannot play a media source.

playbackRates

Type: Array

An array of numbers strictly greater than 0, where 1 represents constant speed (100%), 0.5 represents half speed (50%), 2 represents double speed (200%), and so on. If specified, the Video.js display control (class vjS-Player-Rate) allows the user to select playback speed from an array of selections. Options are displayed in a specified order from bottom to top.

Such as:

videojs('my-player', {
PlaybackRates: [0.5, 1, 1.5, 2]});

Copy the code
sources

Type: Array

A set of objects that reflect the ability of a native element to have a series of child elements. This should be an array of objects with SRC and Type attributes. Such as:

videojs('my-player', {
  sources: [{
    src: '//path/to/video.mp4'.    type: 'video/mp4'
  }, {
 src: '//path/to/video.webm'. type: 'video/webm'  }] });  Copy the code

Using the element will have the same effect:

<video ... >  <source src="//path/to/video.mp4" type="video/mp4">
  <source src="//path/to/video.webm" type="video/webm">
</video>

Copy the code
techCanOverridePoster

Types: Boolean

Make it possible for technicians to overlay the player’s poster and integrate into the player’s poster lifecycle. This can be useful when using multiple technologies, each of which must set up its own poster when playing a new source.

techOrder

Enter: Array, default: [‘ html5 ‘]

Defines the preferred order of the video.js technology. By default, this means Html5 preferred technology. Other registered technologies will be added after this technology in their registered order.

nativeVideoTracks

Types: Boolean

You can set it to false to disable native video track support. Most often used in videojs-contrib-hls.

nativeControlsForTouch

Types: Boolean

Only technology supports Html5, and this option can be set to true to force touching the device’s native controls.

Beautify the video.js wheel

The play button is centered

After using the simple way above, we will find that the video to play page looks like this:


The default play button is in the upper left corner, which the author thinks will block the content, but this can be modified according to parameters. We just need to add a class (VJS-big-Play-centered) to the label of the video.

<video ref="videoNode" class="video-js vjs-default-skin vjs-big-play-centered"></video>
Copy the code

The effect is as follows:


Loading state beautification

There is a default loading in video.js when playing videos. Here I provide a way to customize the loading page according to my own ideas. If there is any mistake, please correct it.

Main ideas:

A layer of div is suspended above the player to display the content in the custom loading, and then a variable value is used to control whether the div is loaded or not. The value of the variable is updated by monitoring a loading state of the video, so as to achieve the purpose of the custom loading page.

Main code:

Template note: not the complete code, just the key code

<div :style="{width:'100%',position:'relative',height:height}">
    <div data-vjs-player style="width:100%">
      <video ref="videoNode" class="video-js vjs-default-skin vjs-big-play-centered"> </video>    </div>
    <div
 v-if="loading"  :style="{width:'100%',height:height,position:'absolute',left:'0px',top:'0px'}"  >  <img  :style="{width:'100%',height:height}"  src="https://img.zcool.cn/community/0113b1576a43e90000018c1b87042d.gif"  />  </div> </div> Copy the code

Script Note: Not complete code, just key code

data() {
    return {
      loading: false
    };
 },
 let options = {  autoplay: false, // Auto play. Omit code }; this.player = videojs(  this.$refs.videoNode,  options,  function onPlayerReady() {  videojs.log(`Your player${self.index}is ready! `); _this.loading = true;  _this.player.play();  _this.player.one("playing".function() { // Listen for playback // console.log("Player starts playing");  _this.loading = false;  });   } ); Copy the code

The effect is as follows:


Of course, you can also customize the content.

Video dot

In daily life, when we watch videos, we often see that there are some small dots on the progress bar of some videos, and then some text hints will appear when the mouse is put on the progress bar, so can we add this function on the Web player? Of course it can!

First, I looked for a bunch of wheels and finally found the Videojs-markers wheel to do just that.

Install videojs – markers
npm i videojs-markers -S
Copy the code
Introduction of videojs – markers
import "videojs-markers";
// Introduce stylesimport "videojs-markers/dist/videojs.markers.css";
Copy the code
Use videojs – markers
this.player.markers({
  markerStyle: {
// Mark the dot style    width: "0.7 em".    height: "0.7 em". bottom: "-0.20em". "border-radius": "50%". "background-color": "orange". position: "absolute"  }, // Cursor cursor cursor cursor markerTip: {  display: true// Whether to display/ *A callback function for dynamically building token-prompt text.You simply return a string, and the parameter marker is the tag object passed to the plug-in* / text: function(marker) {  return marker.text;  }  },  markers: [  {  time: 20,  text:'Point one'  },  {  time: 40,  text:'Point two'  },  {  time: 130,  text:'Point three'  },  {  time: 200,  text:'Point four'  } ].}); Copy the code

The effect is as follows:


Packaging components

With the basic functionality of the player in place, the final step is to encapsulate the components. The idea of encapsulation is simply to pass in some modified properties from the parent component as props.

Commonly used attributes that need to be encapsulated

Note: this is only part of the list, can be added or deleted according to the actual situation

  • SRC: indicates the address of the video or live broadcast
  • Height: indicates the height of the player
  • Controls: Whether the control bar needs to be displayed
  • Markers: Identifies the video feed
  • Type: indicates the type of the video

Based on these properties, let’s transform our component

template

<template>
  <div :style="{width:'100%',position:'relative',height:height}">
    <div data-vjs-player style="width:100%">
      <video ref="videoNode" class="video-js vjs-default-skin vjs-big-play-centered"> </video>    </div>
 <div  v-if="loading"  :style="{width:'100%',height:height,position:'absolute',left:'0px',top:'0px'}"  >  <img  :style="{width:'100%',height:height}"  src="https://img.zcool.cn/community/0113b1576a43e90000018c1b87042d.gif"  />  </div>  </div> </template> Copy the code

script

data() {
    return {
      player: null,
      loading: false
    };
},   let options = {  // autoplay: true, // Auto play language: "zh-CN".Controls: this. Controls, // Control bar preload: "auto", // automatic loading errorDisplay: true// Error display // fluid: true// Follow the size of the outer container, follow the width of the outer container width: "100%". height: this.height,  // controlBar: false/ / set tofalseDo not render the control bar DOM element, just set controls tofalseIt's not on display, but it's there // textTrackDisplay: false// Do not render subtitle related DOM userActions: {  hotkeys: true// Whether hotkeys are supported },  notSupportedMessage: "This video cannot be played, please try again later.". techOrder: ["flash"]. sources: [  {  src: this.src,  type: this.type  }  ]  };  let _this = this;  this.player = videojs(  this.$refs.videoNode,  options,  function onPlayerReady() {  videojs.log(`Your player${self.index}is ready! `); _this.loading = true;  _this.player.play();  _this.player.one("playing".function() { // Listen for playback // console.log("Player starts playing");  _this.loading = false;  });  }  );  videojs.addLanguage("zh-CN", videozhCN);  if (this.markers) {  this.player.markers({  markerStyle: { // Mark the style width: "0.7 em". height: "0.7 em". bottom: "-0.20em". "border-radius": "50%". "background-color": "orange". position: "absolute"  },  markerTip: {  display: true./ *A callback function for dynamically building token-prompt text.You simply return a string, and the parameter marker is the tag object passed to the plug-in* / text: function(marker) {  return marker.text;  }  },  markers: this.markers,  });  } Copy the code

Dynamic switching video encapsulation

When the video is playing, we often have the need to switch the video, so how to encapsulate this? Simply listen for SRC changes in the component. If SRC changes, reload the video and play the video as follows:

watch: {
    src() {
      if (this.player) {
        let _this = this;
        this.loading = true; // Display the loading status again let myPlayer = this.player;  myPlayer.off("timeupdate"); // Clear the timemyPlayer.reset(); // Reset the playermyPlayer.pause(); // Pause the playbackMyplayer.src ([// reset the source of the player {  src: this.src,  type: "rtmp/flv"  }  ]); myPlayer.load(this.src); // Reload the videomyPlayer.play(); // Play the video myPlayer.one("playing".function() { // Load complete, start playing // console.log("Player starts playing");  _this.loading = false; // Hide the loading state });  }  } }, Copy the code

So a simple video player is packaged.

Use the sample

Component package completed, unavoidable use, the code is as follows:

<template>
  <basic-container>
    <el-row class="video-test">
      <el-col :span="16" class="video-test-left">
        <videoPlayer :controls="true" height="600px" :src="url" type="video/mp4" :markers="markers"/>
 </el-col>  </el-row>  </basic-container> </template> <script> import videoPlayer from "@/components/videoPlayer/videoPlayer"; export default {  components: { videoPlayer },  data() {  return {  url: "http://127.0.0.1/test.mp4". markers: [  {  time: 20,  text:'Point one'  },  {  time: 40,  text:'Dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2 dot 2'  },  {  time: 130,  text:'Dot three dot three dot three dot three dot three dot three dot three dot three dot.'  },  {  time: 200,  text:'Dot four, dot four, dot four, dot four, dot four, dot four.'  }  ]  };  } }; </script> <style lang="scss"> </style> Copy the code

Reference:

Videojs, https://blog.csdn.net/a0405221/article/details/80923090 Chinese documents

Recent good articles recommended:

1, the history of the strongest VUE summary ~ ten thousand words long – interview development depends on it

2. With it, your project will be faster than a rocket

I know. What are macro tasks and micro tasks?

4, sharp code non weapon vscode

Interview guide takes you to the top of your life

Finally, if you want to discuss and explore the front end with me, you can pay attention to my public number, update dry goods irregularly, pay attention to the background reply knowledge system, more can receive xiaobian carefully prepared front-end knowledge system, future learning is no longer confused. More can join the technical group exchange discussion.

This article is formatted using MDNICE