background


Recently, the company added a Video module in the project, but the product thought the control bar of the Video was a little LOW, so it designed one by itself. So began the custom Video control pit mining trip.

Homepage effect picture:

When the mouse on the picture, automatically play video, and display preview progress bar, when the mouse away, show preview picture, hover picture again, continue to play last time

Renderings of the video details page:

  • Can customize pause and play
  • Imitate the progress bar to achieve drag and drop playback speed
  • Display current time
  • Can choose double speed
  • You can control the sound
  • Can play in full screen

The next step is implementation

First of all, the structure code of kangkang home page:

               <div class="clickL video-box" @mouseover="play(item3.images_id)" @mouseout="pause(item3.images_id)">
                    <img v-lazy="item3.picture" width="268" alt="" v-show="id ! = item3.images_id">
                    <video class="video-hover" ref="videoAll" onMouseOver="this.play()" :src="item3.short_video" @timeupdate="commonVideoUpdata(index)" width="268px" height="176px" onMouseOut="this.pause()" muted loop="loop">
                    </video>
               </div>
                <div class="process-slider common-progress" v-show="id == item3.images_id">
                      <el-slider v-model="currentTimeProgress" :show-tooltip="false" input-size="small"></el-slider>
                </div>
Copy the code

Here’s the idea:

1. Judge user mouse events and switch pictures and videos.

2. Video Needs to obtain other instances through video for DOM manipulation. The classification of mouse moving and mouse sliding in and out of video is to control video playing and stopping, and play and pause are built-in methods of video. See here for more tips

3. The progress bar here uses Element’s slider component. By default, Max is 100.

CSS section code:

.video-box { position: relative; height: 176px; &>img { width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 2; } &>video { object-fit: fill; // Stretch the filling box to make sure it is as big as the picture}}Copy the code

In the CSS part, it is important to make the video display the same width and height as the picture, otherwise the picture will be large and the video will be small, as shown in the figure:

Logical part:

data() {
     return}}, methods:{// start play(val) {this.id = val}, {this.id = 0 this.currentTimeVal = 0}, // Public Video commonVideoUpdata(id) {let videoObj = this.$refs.videoAll
            console.log(videoObj);
            letCurrTime = videoObj[id]. CurrentTime // currentTimeletDuration = videoObj[id]. Duration // Total timeletpre = currTime / duration this.currentTimeProgress = pre * 100; }},Copy the code

We use video’s timeUpdate built-in method to get the current playback time and get the current DOM element. VideoObj prints an array:



Pay attention to the pit point

At the end of this home page function, then implement a custom control bar for the details page.

HTML part:

 <div class="detali_box_img video-media">
                <div class="video-example">
                  <video :src="item.video_file" width="100%" height="100%" loop="loop" preload="auto" @timeupdate="videoTimeUpdate" @click="controlVideo" ref="videoCon"> Your browser does not support the video TAB. </video> </div> // Pause button in video <div class="play-btn" @click="controlVideo" :style="[opcityVal]"></div> // Control bar play and pause buttons <div class="control-play">
                  <p class="control-play-btn" @click="controlVideo">
                    <span class="el-icon-video-play" v-show=! "" vcIsPlay"></span>
                    <span class="el-icon-video-pause" v-show="vcIsPlay"></span> </p> // Play progress bar <div class="control-progress common-progress">
                    <div>
                      <el-slider v-model="vcProgress" :show-tooltip="false" :max="durationProgress" input-size="small" @change="getNewTime"></el-slider> </div> <! -- <p class="control-progress-item"></p> --> </div"current-time">{{vcCurrentTime}}</div> // Total video length <div class="duration">{{item.duration_time}}</div> // Speed control <div class="video-speed-box" @click="getPlayBackRate">
                    <el-dropdown placement="bottom" @command="handleCommand"> <! -- <span class="el-dropdown-link"> -->
                      <span class="video-speed-show">{{speedTime}}</span> <! -- </span> --> <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item command="1"> 0.5 x < / el - dropdown can - item > < el - dropdown can - itemcommand="2">1x</el-dropdown-item>
                        <el-dropdown-item command="3"> 1.5 x < / el - dropdown can - item > < el - dropdown can - itemcommand="4">2x</el-dropdown-item>
                        <el-dropdown-item command="5">3x</el-dropdown-item> </el-dropdown-menu> </el-dropdown> </div> // Volume control <div class="control-voice common-progress">
                    <span class="voice-icon"></span>
                    <div class="voice-slider">
                      <el-slider v-model="voiceProgress" input-size="small" @change="getNewVoice"></el-slider> </div> </div> // Full screen <p class="fullscreen" title="Full screen" @click="getFullSceen">
                    <span class="el-icon-full-screen"></span>
                  </p>
                </div>
              </div>
Copy the code

The CSS section ignores… First of all, the data part:

      vcIsPlay: falseOpcityVal: {opacity:'1'}, currentTimeVal: 0, vcCurrentTime: 0'00:00:00'DurationProgress: 0, // The total duration of the current video speedTime:'1x'// voiceProgress: 0 // SoundCopy the code

Pause and play:

// Play and pause the videocontrolVideo() {
      let videoObj = this.$refs.videocon this.durationProgress = videoObj[0].duration // Total timeif (this.vcIsPlay) {
        videoObj[0].pause()
      } else{ videoObj[0].play() } this.vcIsPlay = ! this.vcIsPlay this.opcityVal.opacity = this.opcityVal.opacity =='1' ? '0' : '1'
    },
Copy the code

Call the two methods provided directly, and then use vue’s style binding to control the explicit and implicit of the pause button. The progress bar here is the same as element’s slider component, but THE Max value is changed to the total length, in seconds. Please be patience to see below.

Progress bar:

// Get the timevideoTimeUpdate() {
      let videoObj = this.$refs.videoCon
      letCurrTime = videoObj[0].currenttime // currentTime this.vcProgress = currTime // assign the progress bar this.vcCurrentTime = this.getFormatVideoTime(currTime) console.log(this.vcCurrentTime) //"00:00:27"}, // format time getFormatVideoTime(time) {let curtime = time
      let h = parseInt(curtime / 3600)
      let m = parseInt((curtime % 3600) / 60)
      let s = parseInt(curtime % 60)
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      return h + ':' + m + ':' + s
    },
Copy the code

The challenge here is, how do I drag the progress bar to control it? Don’t panic, look at the code:

@change="getNewTime"// Element's sliding component has a chang event getNewTime(val) {let videoObj = this.$refs.videoCon
      console.log(val)
      videoObj[0].currentTime = val
    },
Copy the code

Change the progress bar and reassign to the current time

Double speed part:

HandleCommand (val) {handleCommand(val) {let videoObj = this.$refs.videoCon
      switch (val) {
        case '1': videoObj[0]. PlaybackRate = 0.5 this.speedTime ='0.5 x'
          break
        case '2':
          videoObj[0].playbackRate = 1
          this.speedTime = '1x'
          break
        case '3': videoObj[0]. PlaybackRate = 1.5 this.speedTime ='1.5 x'
          break
        case '4':
          videoObj[0].playbackRate = 2
          this.speedTime = '2x'
          break
        case '5':
          videoObj[0].playbackRate = 3
          this.speedTime = '3x'
          break

        default:
          videoObj[0].playbackRate = 1
          this.speedTime = '1x'
          break}},Copy the code

Look at the picture:

Sound section:

// Set the sound getNewVoice(val) {let videoObj = this.$refs.videoCon
      letVideoObj [0]. Volume = newVc // assignment}Copy the code

I also use the sliding component, Max value remains the default 100, and then divide the default value into 100 when sliding. For example, the new value of the current slider is 50, and the obtained value is a legal value within the range of [0-1] after dividing 100. If the volume value provided by Video is not between 0 and 1, an error will be reported

Finally, the full screen section:

// Full screen playbackgetFullSceen() {
      let videoObj = this.$refs.videoCon
      videoObj[0].webkitRequestFullScreen()
    },
Copy the code

But I see there is a method on the Internet is to simulate the whole f11 press, if interested can also understand!

conclusion

Because there is no very carefully before make a video, so a lot of built-in properties and methods of it don’t know, he has no experience was afraid and scared scared, it’s like to fall in love, ha, ha, ha, then the group leader’s support and encouragement, I am bold attempt, after the success, the experience gave me a big confidence, the function of the feeling after the write other didn’t do it, don’t panic, After all, the hard part is already written by the guys who wrote elementUi, standing on the shoulders of giants, so to speak, hahaha! Worship the big guy. We’ll have to work harder.