播放器 - 自定义播放进度条

5,367 阅读1分钟

这是我参与更文挑战的第8天,活动详情查看: 更文挑战

自定义播放进度条

下面先贴出示例代码(js 是原生的,可以放心使用)。

<div class="video-box">
  <!-- 强行插入苹果广告 -->
  <video src="iphone12.mp4"></video>
  <!-- 控制条 -->
  <div class="ctrl-box">
    <!-- 进度条 -->
    <div class="progress-box">
      <div class="progress"></div>
    </div>
    <div class="play-btn">播放/暂停</div>
    <div class="progress-time">00:00/00:00</div>
  </div>
</div>

<script>
  var video = document.querySelector('video')
  var progressBox = document.querySelector('.progress-box')
  var progress = document.querySelector('.progress')
  var progressTimer = null // 进度 timer
  
  // 计算时长,注意:这里的 padStart 是 es7 语法
  function parseTime(value){
    if (!value) return ''   
    let interval = Math.floor(value)
    let minute = (Math.floor(interval / 60)).toString().padStart(2, '0')
    let second = (interval % 60).toString().padStart(2, '0')
    return `${minute}:${second}`
  }
  // 推进进度条
  function changeProgress() {
    var timeStr = parseTime(video.currentTime) + '/' + parseTime(video.duration)
    document.querySelector('.ctrl-box .progress-time').innerText = timeStr
    var percent = video.currentTime / video.duration
    progress.style.width = percent * 100 + '%'
  }
  // 点击进度条的任意地方
  progressBox.onclick = function (e) {
    clearInterval(progressTimer)
    var length = e.pageX - progressBox.offsetLeft
    var percent = length / progressBox.offsetWidth
    video.currentTime = percent * video.duration
    video.play()
    progressTimer = setInterval(changeProgress, 60)
    // 显示视频在播放的样式
    // ...
  }
  // 播放&暂停点击
  document.querySelector('.play-btn').onclick = function () {
    if (video.paused) {
      // 播放后,需要推进进度条
      video.play()
      progressTimer = setInterval(changeProgress, 60)
    } else {
      // 暂停后,需要停止推进进度条
      video.pause()
      clearInterval(progressTimer)
    }
  }
</script>

<style>
  /*
    样式简单写了下,大概就是
    progress-box: 写一个固定的宽度,用相对定位,写个边框颜色
    progress: 写个背景颜色,宽度随 js 改变即可
   */
   * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    .video-box {
      width: 100%;
      height: auto;
    }
    video {
      width: 100%;
    }
    .ctrl-box {
      width: 80%;
      margin: 0 auto;
    }
    .ctrl-box .progress-box {
      position: relative;
      height: 30px;
      margin-bottom: 10px;
      background: rgba(0, 0, 0, 0.1);
      border-radius: 8px;
      border: 1px solid rgb(131, 175, 155);
      overflow: hidden;
      cursor: pointer;
    }
    .ctrl-box .progress-box .progress {
      position: absolute;
      top: 0;
      left: 0;
      width: 0%;
      height: 100%;
      background: rgb(131, 175, 155);
    }
    .ctrl-box .play-btn {
      display: inline-block;
      margin-right: 20px;
      cursor: pointer;
    }
    .ctrl-box .progress-time {
      display: inline-block;
    }
</style>

效果图:

640.gif

其实实现并不难,只要知道怎么获取得到 video 的已播放时长和总时长。使用以下公式就可以推出进度条的进度,然后再将进度转化为样式即可。

进度 = 已播放时长/总时长

要注意一个地方,通常进度条是可以随意点击,当进度条被点击后,视频进度需要跳到对应的时间点上。这个实现只需要得知用户鼠标点击的 x 坐标、进度条的 x 坐标、进度条的总宽度和视频总时长这四个值,用以下公式就可以得知视频需要跳到哪个目标时间点了。 (均假设以 body 左边框为 x 轴)

进度条宽度 = 鼠标x坐标 - 进度条x坐标
比例 = 进度条宽度 / 进度条总宽度
目标时间点 = 比例 * 视频总时长
video.currentTime = 目标时间点

image.png

亲们不用重复造轮子了,直接复制粘贴,改样式吧。