Go to comments

HTML5 提升 综合练习(视频插件)

一、音视频API

音/视频属性

属性名含义
currentTime当前播放时间,单位为秒。为其赋值将会使媒体跳到一个新的时间。
loop对应HTML标签loop属性,决定该媒体是否循环播放.
controls对应HTML标签controls属性,控制是否显示用户播放界面的控制 HTML
src对应HTML标签src属性,获取和设置播放地址
volume表示音频的音量。值从0.0(静音)到1.0(最大音量)
playbackRate播放倍速。1为正常。
duration总时长,单位为秒。
paused当前是否是暂停状态,暂停返回true,播放返回false
muted是否静音,静音返回true,有声音返回false


音/视频方法

方法名含义
play()开始播放
pause()暂停播放


事件

事件名含义
pause暂停时触发
ended结束时触发
play开始播放时触发
timeupdate属性currentTime变化时触发。会随着播放进度的变化不断触发
loadedmetadata已加载元数据
loadeddata事件在第一帧数据加载完成后触发


<video> 视频嵌入元素

https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video


二、播放器

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>播放器</title>
<style>
  body,
  button,
  input {
    text-align: center;
    color: #444;
    font-size: 14px;
    outline: none;
  }
  video {
    width: 30%;
  }
  .controls {
    margin: 1em 0;
    display: none;
  }
  .active {
    background: #ffbd80;
    color: #fff;
  }
  .loading {
    height: 32px;
    line-height: 32px;
  }
  button {
    border: none;
    padding: 5px;
    background-color: #eee;
  }
</style>
</head>
<body>

<div class="loading">加载中...</div>

<Video src="https://20180416-1252237835.cos.ap-beijing.myqcloud.com/%E8%A7%86%E9%A2%91/hd%20-%20Polina%20Semionova%20_%E5%B7%B4%E8%B5%AB%E7%9A%84%E6%9C%80%E5%90%8E%E4%B8%80%E5%A4%A9_.mp4"></Video>

<div class="controls">
  <button id="btnPlay">播放/暂停</button>
</div>

<div class="controls">
  进度
  <input type="range" id="progress" min="0" max="100" value="0">
  <span id="current">current</span>
  /
  <span id="total">total</span>
</div>

<div class="controls" id="rate">
  播放速率:
  <button data-rate="0.5">0.5倍</button>
  <button data-rate="0.75">0.75倍</button>
  <button data-rate="1">1倍</button>
  <button data-rate="1.25">1.25倍</button>
  <button data-rate="1.5">1.5倍</button>
  <button data-rate="2">2倍</button>
</div>

<div class="controls" id="volume">
  音量:
  <input type="range" min="0" max="100" value="50">
  <span style="width: 30px;display:inline-block;">50%</span>
</div>

<div class="controls">
  <button id="save">保存设置</button>
  <button id="load">加载设置</button>
</div>

<script>

  var doms = {
    // 视频元素
    video: document.querySelector('video'),
    loading: document.querySelector('.loading'),
    btnPlay: document.querySelector('#btnPlay'),
    // 进度条相关元素
    progress: {
      // 进度条
      range: document.querySelector('#progress'),
      // 当前播放时间
      current: document.querySelector('#current'),
      // 总时间
      total: document.querySelector('#total')
    },
    // 播放倍速的容器
    rate: document.querySelector('#rate'),
    // 音量相关元素
    volume: {
      // 滑动块
      range: document.querySelector('#volume input'),
      // 文本
      text: document.querySelector('#volume span')
    },
    // 保存和设置按钮
    buttons: {
      save: document.querySelector('#save'),
      load: document.querySelector('#load'),
    },
    controls: document.querySelectorAll('.controls'),
  }

  // 一、初始化
  doms.video.addEventListener("loadedmetadata", init);

  function init() {
    setProgress();
    setRate();
    setVolume();

    doms.loading.innerText = "加载完成";
    for (var i = 0; doms.controls.length > i; i++) {
      doms.controls[i].style.display = "block"
    }
  }

  /**
   * 01/
   * 根据当前视频进度,设置进度条的状态
   */
  function setProgress() {
    // 1. 设置文本
    doms.progress.current.innerText = formatTime(doms.video.currentTime);
    doms.progress.total.innerText = formatTime(doms.video.duration);

    // 2. 设置进度条
    // x / 100 = 81 / 110
    // x = 当前播放时间 / 总时间 * 100
    // x = Math.floor(doms.video.currentTime / doms.video.duration) * 100;
    doms.progress.range.value = Math.floor(doms.video.currentTime / doms.video.duration * 100);
  }

  // 格式化时间
  function formatTime(sec) {
    // 获取小时
    var hour = Math.floor(sec / 3600);
    sec -= hour * 3600;
    // 获取分钟
    var minute = Math.floor(sec / 60);
    sec -= minute * 60;
    // 获取秒
    sec = Math.floor(sec);

    // 辅助函数
    function _format(n) {
      if (n < 10) {
        return '0' + n;
      }
      return n;
    }

    return _format(hour) + ':' + _format(minute) + ':' + _format(sec);
  }

  /**
   * 02/
   * 设置播放速率的状态
   */
  function setRate() {
    var btns = doms.rate.querySelectorAll('button');
    for (var i = 0; i < btns.length; i++) {
      var rate = btns[i].dataset.rate;
      if (+rate === doms.video.playbackRate) {
        btns[i].classList.add('active');
      } else {
        btns[i].classList.remove('active');
      }
    }
  }

  /**
   * 03/
   * 设置音量
   */
  function setVolume() {
    // console.log(doms.video.volume);
    // 1.设置文本
    var percent = Math.floor(doms.video.volume * 100);
    if (doms.video.muted) {
      percent = 0;
    }
    doms.volume.text.innerText = percent + '%';
    // 2.设置进度条
    doms.volume.range.value = percent;
  }


  // 二、交互

  // 01
  // 播放/暂停
  doms.btnPlay.addEventListener('click', function() {
    if (doms.video.paused) {
      doms.video.play();
      doms.btnPlay.className = 'active';
    } else {
      doms.btnPlay.className = '';
      doms.video.pause();
    }
  });

  // 02
  // 播放时长
  doms.progress.range.addEventListener('input', function() {
    // 比例关系
    // 20 / 100 = x / 110
    // x = 进度条的值 / 100 * 总时长
    doms.video.currentTime = this.value / 100 * doms.video.duration;
    setProgress();
  });

  // timeupdate属性,随着播放进度不断触发
  doms.video.addEventListener('timeupdate', function() {
    setProgress();
  })

  // 03
  // 播放倍速rate
  var btnRates = doms.rate.querySelectorAll('button')
  for (var i = 0; i < btnRates.length; i++) {
    btnRates[i].addEventListener('click', function() {
      doms.video.playbackRate = +this.dataset.rate;
      setRate();
    });
  }

  // 04
  // 音量
  doms.volume.range.addEventListener('input', function() {
    // console.log(this.value / 100);
    doms.video.volume = this.value / 100;
    setVolume();
  });

  // 05
  // 保存设置
  doms.buttons.save.addEventListener('click', function() {
    var obj = {
      currentTime: doms.video.currentTime,
      rate: doms.video.playbackRate,
      volume: doms.video.volume,
    };
    var json = JSON.stringify(obj);
    localStorage.setItem('vdo', json);
    console.log('保存设置', obj);
    doms.loading.innerText = '已经保存设置';
  });

  // 加载设置
  doms.buttons.load.addEventListener('click', function() {
    var str = localStorage.getItem('vdo');
    var obj = JSON.parse(str);
    doms.loading.innerText = '加载设置';
    console.log('加载设置', obj);

    // 加载设置
    doms.video.currentTime = obj.currentTime;
    doms.video.playbackRate = obj.rate;
    doms.video.volume = obj.rate;

    setProgress();
    setRate();
    setVolume();

    // 加载设置后自动播放
    doms.video.play();
  });

  // https://blog.csdn.net/qq_41387882/article/details/121781603
  // https://blog.csdn.net/sunsineq/article/details/109141342?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-5-109141342-blog-126579894.pc_relevant_3mothn_strategy_and_data_recovery&spm=1001.2101.3001.4242.4&utm_relevant_index=8
</script>

</body>
</html>


加了范围限制

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
  .modia{
    width: 800px;
    height: 400px;
    /* margin:0 auto; top:30px; left:200px; border:1px solid #eee; */
    top: 50%;
    left: 50%;
    border:1px solid #eee;
    /* transform: translate(-50%, -50%); */
    margin-top: -200px;
    margin-left: -400px;
    position: absolute;
  }
  .line{
    top: 370px;
    left: 100px;
    width: 600px;
    height: 1px;
    background-color: red;
    position: relative;
  }
  .slider{
    display: block;
    position: absolute;
    top: -9px;
    left: 0;
    height: 20px;
    width: 10px;
    /* border-radius: 50%; */
    background-color: darkred;
    opacity: .5;
  }
</style>
<title>进度滑块</title>
</head>
<body>

<div class="modia">
  <div class="line">
    <span class="slider"></span>
  </div>
</div>

<script>

  // const oDiv = document.getElementsByClassName('line')[0];
  const oSpan = document.getElementsByClassName('slider')[0];

  let disLeft = getElementPosition(oSpan) + 10;
  let disDrap = 0;

  oSpan.onmousedown = function(e){
    document.onmousemove  = function(e){
      disDrap = e.clientX - disLeft;
      if(e.clientX <= disLeft){
        disDrap = 0;
      }
      if(e.clientX >= disLeft + 580){
        disDrap = 580;
      }
      oSpan.style.left = disDrap + 'px';
    }
    document.onmouseup = function(e){
      document.onmousemove = null;
    }
  }

  function getElementPosition(ele){
    if(ele.offsetParent !== document.querySelector('body')){
      return ele.offsetLeft + getElementPosition(ele.parentElement);
    }
    return ele.offsetLeft;
  }

</script>

</body>
</html>


参考

https://www.cnblogs.com/dh-dh/p/9254172.html 用video标签流式加载

https://www.yisu.com/zixun/407340.html html5用video标签流式加载的实现




Leave a comment 0 Comments.

Leave a Reply

换一张