自定义video

h5 video标签 自定义控制条 接触过video标签的人都知道,这个东西是真让人尴尬,尤其是在微信中使用,奇奇怪怪的问题尤其多,上一次的文章中,我已经介绍了一些微信中使用video中的问题了,感兴趣的可以去看一下链接:http://blog.youkuaiyun.com/qq_22557797/article/details/66973548正文从这里开始这里主要介绍自定义控制条中控制条所包含的一系列常用事件,主要是 播放/暂停 刷新 音量开 阅读详情

需求

  1. 播放暂停切换
  2. 播放进度条反馈和控制 (拖拽 点击) 播放时间 00:00/05:30
  3. 音量调控 反馈 一键静音/取消静音
  4. 全屏播放 循环模式
  5. 播放状态反馈 未播放 已播放 播放完毕
  6. 本地存储播放时间 自动续播

准备

        [
	        {
	          方法:[ play(),pause()],
	          属性: [paused],
	          element:[#contr-play]
	        },{
	          方法:[ mousedown,pause,mousemove,mouseup,play],
	          属性: [currentTime],
	          element:[player-progress,progress-line,progress-unit,player-time,player-current]
	        },{
	          方法:[ mousedown,mousemove,mouseup],
	          属性: [volume,muted],
	          element:[]
	        },{
	
	        }

        ] 
        
        * video设置currentTime的时候 会触发 canplay事件

        * 拖拽进度条之后 播放视频

        点击进度条某个位置 直接开始跳转播放 

        click {
          mousedown 
          mouseup
        }

效果

在这里插入图片描述

实现

<!DOCTYPE html>
<html lang="zh-cn">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>video 播放器</title>
  <style>
    @font-face {
      font-family: "iconfont";
      src: url('fonts/iconfont.eot?t=1600426546624');
      /* IE9 */
      src: url('fonts/iconfont.eot?t=1600426546624#iefix') format('embedded-opentype'),
        /* IE6-IE8 */
        url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAS4AAsAAAAACZwAAARrAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDSAqGEIUYATYCJAMYCw4ABCAFhG0HWBtOCFGULspqsq+wKWO+GKJwXogXwkCjQQ+Evn05o/Tmdn/CWtgG7CKF5wDBE+3X3uzO7ldJh0qDrg1PXronIomYrETRBCXeT3b2b3lEpbkvLFIehM2H9pLZzSaenZwqqfxQaVQqGrOyuvDwtnv/7k9So5BJKoGZTRUuRKGkK0x2QTiRPI44CCLOEosr0+0G0l/4RJO7B8EAIYJA47YGzrlqkEjLIJhA8XigAzpJpmAVUP1xr+qf5x8s61myQaI496BcKFwuUIHGXmQtSLmCWgewTbzfuh4CYqPWYKb61l6Ip/TdBMhpmTrEJ+y0ghKhyRccm8gHgrDcszcAePB+Xn5wJB4MV9FvdLjVuaGyp3ePG401m+oojA7nBdiTwIJlgELeQv8FLsgv48TyX+BtA1IhQ/tqFrOS69292J+EWg+L1PiXB46lDIEMQJ9S5K7OHaDCkkeGYlixMFTCisJwDGwY/N9TXpbZD9gzAPwBiGwk6QcOfgcvpWOqmuni+nDbJCffPri99vX5c4JDgObuNOtT9Qobn1udt1pvXyqbSOFmnLnrUp1xT05in3ORNC6+nT8KbDu2cILh7o5rl+7K1J35e9b7WiHOI4LWDRwQhtIW7srqIIzWBM4jQrddyno3JkG8WNmroq/UENHQrkXGZmh3yKq0M7oO1tmbuCt311QH7T+SszNH3zmavW3H1gfaO3fpCqqAIVBbk3Rl6+lFYfQpjxD/1LCiaKujjpQD+89yHz9y0JxlpFBTnnAd1a2FWEvuByU7/O7KqNeXCjfdL1cSSuJRmNo0Bpn8r4CxZCUHHcjbCN6cUle4Ls4hLHIutpit6Y6v6lp58hMru1btw3RqwOWJcnTx2zmdm0nVEhLUh2y1sY2ZRsiMJ91hePo8SkrtC2z+X28ZH25J8x/lc11WCMukL2WvGeIKj5MKnvzeVZWYhp/oVg54db9lpL7krXtXOz+MYaIn3rxmf0cKGU2aLN3uOQqu3RZ9sPmavnmV/5xqhowU6qgjOVx+IowrAqhXhNR4GWQA/BR+4datAgD7sL8Y/reDi/+X/Q6P6ylpaaV/QlEAPuYvOLy+4WiCbQB/FQONFf8pRcM5VVS6w6c02xpCgLf/sbIGxMYS/JPCtVdDBTsQeUXIKQBGYASs0DSq5DI4iVXwQmsQW9JwcqJBcCQjYNEUAaJ0BozcM1ilm6iSL8HpfQGvDAexo8g6Z2I2VmINwTrFbtQ/jCxXKGiYLprot3ZjM+rXSVzl0TRMbCuFVElJlxpwEJMhDrAHTAelBjJIKIDqiZthvz+EwiTkxS4qeSgNF8uyUfRFkisUgERbCExHYW5Iv2GIxSUkyHBWphIz398NM0X56UjFTFlUgxE2a+2ISqI0QBv0wUYzl/IS2wCTA0UZEAMREoDUE17Mb+RDkHDxVl6YCyXxdMiGFZPJRUZTvTS9MXCXVwEx/aN8GLGi4sRLgLv1qI3jhqJBT1QPxg9bQb+lB834SGLzsBU0xU6/PowJAAA=') format('woff2'),
        url('fonts/iconfont.woff?t=1600426546624') format('woff'),
        url('fonts/iconfont.ttf?t=1600426546624') format('truetype'),
        /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
        url('fonts/iconfont.svg?t=1600426546624#iconfont') format('svg');
      /* iOS 4.1- */
    }

    .iconfont {
      font-family: "iconfont" !important;
      font-size: 32px;
      color: #ccc;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      cursor: pointer;
    }

    .icon-pause:before {
      content: "\e7d2";
    }

    .icon-loop:before {
      content: "\e6a9";
    }

    .icon-volume:before {
      content: "\e63a";
    }

    .icon-fullscreen:before {
      content: "\e640";
    }

    .icon-player:before {
      content: "\e62b";
    }

    div {
      box-sizing: border-box;
    }

    video {
      display: block;
      width: 100%;
      max-height: 100%;
    }

    .player {
      position: relative;
      display: flex;
      flex-direction: column;
      justify-content: center;
      width: 638px;
      height: 493px;
      margin: 100px auto;
      background-color: #000;
    }

    .player .hint {
      position: absolute;
      top: 0;
      width: 100%;
      height: 30px;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 20px;
      letter-spacing: .2em;
    }

    .player-screen {
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      display: flex;
      justify-content: center;
    }


    .player-controls {

      display: flex;
      flex-direction: column;
      justify-content: space-between;
      align-items: center;
      position: absolute;
      bottom: 0;
      width: 100%;
      height: 60px;
    }


    .player-progress {
      position: relative;
      width: 100%;
      height: 4px;
      background-color: #ccc;
    }

    .player-progress:hover .progress-unit {
      display: block;
    }

    .player-progress .progress-line {
      position: relative;
      width: 0;
      height: 4px;
      background-color: rgb(18, 177, 226);
    }

    .player-progress .progress-unit {
      display: none;
      position: absolute;
      right: -18px;
      top: 0;
      bottom: 0;
      margin: auto;
      width: 18px;
      height: 18px;
      border-radius: 50%;
      background-color: rgb(18, 177, 226);
      cursor: pointer;
    }

    .player-time {
      position: absolute;
      right: 0;
      top: -35px;
      color: #fff;
    }

    .player-controls .player-operator {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      padding: 4px 20px;
    }

    .operator-right {
      display: flex;
      align-items: center;
    }

    .operator-right i {
      padding: 0 6px;
    }


    .is-loop {
      color: pink;
    }

    .is-muted {
      color: red;
    }

    .volume-range {
      width: 100px;
      height: 5px;
    }
  </style>
</head>

<body>
  <div id="my-player" class="player">
    <p class="hint">暂未播放影片</p>
    <div class="player-screen">
      <video src="video/mp4.mp4">
        <source src="video/mp4.mp4" type="video/mp4">
      </video>
    </div>

    <div class="player-controls">
      <div class="player-progress">
        <p class="player-time"><span class="player-current">00:00:00</span> / <span class="player-count">00:00:00</span>
        </p>
        <div class="progress-line">
          <div class="progress-unit"></div>
        </div>
      </div>
      <div class="player-operator">
        <i id="contr-play" class="iconfont icon-player icon-pause"></i>

        <div class="operator-right">
          <input type="range" value="0.1" id="volume-range" class="volume-range">
          <i id="contr-volume" class=" iconfont icon-volume"></i>
          <i id="contr-loop" class=" iconfont icon-loop"></i>
          <i id="contr-full" class=" iconfont icon-fullscreen"></i>

        </div>
      </div>
    </div>
  </div>
  <script src="js/common.js"></script>
  <script src="js/Storage.js"></script>
  <script>
    class MyVideo {
      static progressMaxWidth = $('.player-progress').offsetWidth;

      constructor(player = $('video')) {
        this.player = player;
        this.canPlay = false; //视频可播放状态 视频加载到可以播放状态的时候 canPlay 为true 默认false
        this.storage = new Storage('local');
        this.$ele = {
          $playBtn: $('#contr-play'), //播放|暂停按钮
          $progress: $('.progress-line'), //进度条
          $progressUnit: $('.progress-unit'), //进度条按钮
          $currentTime: $('.player-current'), //当前播放时长
          $countTime: $('.player-count'), //总时长
          $fullScreen: $('#contr-full'),//全屏按钮
          $loop: $('#contr-loop'), //切换循环loop状态
          $volumeBtn: $('#contr-volume'),
          $volumeRange: $('#volume-range'),
        }
        //进度条数据集
        this.progress = {
          isDown: false, //是否按下鼠标
          startX: 0, //起始鼠标x方向位置
          width: 0, //起始进度条宽度
        };
        //事件总控制
        this.eventListener();
      }

      //设置触发 左查询 写入
      set isPaused(val) {
        this._paused = val;
        if (val) {
          this.myPlay();
          return false;
        }
        this.myPause();
      }


      //获取触发 右查询 读取
      get isPaused() {
        return this._paused; //return的值会作为 isPaused属性的值
      }


      set volume(val) {
        this._volume = val;
        this.player.volume = val;
        this.$ele.$volumeRange.value = val * 100;
      }


      get volume() {
        return this._volume;
      }


      //初始化
      initPlayer() {

        if (this.canPlay) {
          return false;
        }
        this.volume = 0.1;
        this.player.volume = this.volume; //初始化音量
        this.canPlay = true; //初始化可播放状态

        this.checkPlayHistory();//检查本地存储该视频是否有播放时间戳 如果存在设置播放时间戳跳转
        this.setCountTimeText()//初始化总播放时长
        this.setCurrentText(); //初始化当前播放时长
      }

      checkPlayHistory() {
        let current = ~~this.storage.getStorage(this.player.src);
        if (!current) {
          return false;
        }
        this.setCurrentTime(null, current);
      }

      eventListener() {
        //事件分发映射表
        const dragMap = {
          'mousedown': (e) => {
            const target = e.target;

            //按下鼠标的时候 判断触发元素是否是progress-unit
            if (e.target.className === 'progress-unit') {
              //拖拽流程
              if (this.progress.isDown) {
                return false;
              }
              this.progress.startX = e.clientX;
              this.progress.isDown = true;
              this.progress.width = this.$ele.$progress.offsetWidth;
              this.isPaused = false;

              return false; //终止后续执行
            }

            //类名中是否包含progress 判断是否点击在 进度条上 => 进度跳转
            if (/progress/g.test(e.target.className)) {

              let _x = e.clientX - getPosition($('.player-progress')).left;
              let ratio = _x / MyVideo.progressMaxWidth;
              let time = ratio * this.player.duration;
              this.setCurrentTime(null, time);
              this.isPaused = true;
            }
          },
          'mousemove': (e) => {
            if (!this.progress.isDown) {
              //如果没有开启拖拽 
              return false;
            }
            //_x 鼠标拖拽x方向位移增量
            let _x = e.clientX - this.progress.startX;
            //width 当前进度条宽度 = 增量+初始宽度
            let width = _x + this.progress.width;

            //ratio 比例 = 当前宽度/总宽度
            let ratio = width / MyVideo.progressMaxWidth;
            //time 当前播放市场 = 比例 * 总时长 
            let time = ratio * this.player.duration;
            this.setCurrentTime(null, time);
          },
          'mouseup': (e) => {
            if (!this.progress.isDown) {
              //如果没有开启拖拽 
              return false;
            }
            this.isPaused = true; //set isPaused
            this.progress.isDown = false;
          }
        }

        //事件控制器 监听
        this.$ele.$playBtn.addEventListener('click', () => {
          //获取暂停当前状态 isPaused true暂停 false播放
          this.isPaused = this.player.paused;
          //监听播放/暂停按钮的点击
          if (!this.canPlay) {
            //判断是否可以播放 默认true
            return false;
          }

        }, false);

        //监听可播放状态 调用 initPlayer
        this.player.addEventListener('canplay', this.initPlayer.bind(this));

        //播放时间更新触发
        this.player.addEventListener('timeupdate', this.setCurrentTime.bind(this));

        //监听全屏切换按钮
        this.$ele.$fullScreen.addEventListener('click', this.changeFullScreen.bind(this));

        this.$ele.$loop.addEventListener('click', this.changeLoop.bind(this));

        this.$ele.$volumeRange.addEventListener('change', this.changeVolume.bind(this), false);

        this.$ele.$volumeBtn.addEventListener('click', this.chageMuted.bind(this), false);

        //当页面完全不可见的时候  存储视频播放信息
        document.addEventListener('visibilitychange', () => {
          if (document.hidden) {

            this.isPaused = false; //暂停视频
            this.setVideoInfo();
          }
        });


        //事件分发 
        const drag = (e) => {
          let type = e.type;
          if (dragMap.hasOwnProperty(type)) {
            dragMap[type](e);
          }
        }

        //监听进度条的拖拽组
        document.addEventListener('mousedown', drag, false);
        document.addEventListener('mousemove', drag, false);
        document.addEventListener('mouseup', drag, false);


      }

      //设置进度条
      setProgress(done) {
        //进度条比例 .progress-line 的宽度  = 当前播放(秒)/视频总时长(秒) * 100 + '%'

        let ratio = this.player.currentTime / this.player.duration * 100;
        if (done) {
          this.progress.width = ratio * MyVideo.progressMaxWidth;
          return false;
        }
        //设置进度条DOM的宽度样式
        this.$ele.$progress.style.width = ratio + '%';

      }

      //设置当前播放时间反馈
      setCurrentTime(e, time) {
        if (time) {
          this.player.currentTime = time;
        }
        //设置进度条
        this.setProgress();
        //设置当前播放时间text
        this.setCurrentText();
      }


      //设置当前播放时间文本
      setCurrentText() {
        this.$ele.$currentTime.innerText = this.getCurrentTime();
      }

      //设置总时长文本
      setCountTimeText() {
        this.$ele.$countTime.innerText = this.getCountTime();
      }

      //获取总时间 s=> h:m:s
      getCountTime() {
        //duration 视频总时长
        return MyVideo.fromatTime(this.player.duration);
      }

      //获取当前播放时长 s=> h:m:s
      getCurrentTime() {
        return MyVideo.fromatTime(this.player.currentTime);
      }


      //静态方法 内部的工具方法
      static fromatTime(time) {
        let [s, m, h] = [~~(time % 60), ~~(time / 60), ~~(time / 3600)];
        [s, m, h] = [s, m, h].map(padLeft);
        return `${h}:${m}:${s}`;
      }


      //播放动作
      myPlay() {
        this.$ele.$playBtn.classList.remove('icon-player');
        this.player.play();
      }


      //暂停动作
      myPause() {
        this.$ele.$playBtn.classList.add('icon-player');
        this.player.pause();
      }

      //全屏切换
      changeFullScreen() {
        if (!isFullScreen()) {
          openFullScreen(this.player);
          return false;
        }
        closeFullScreen();
      }


      //切换循环状态
      changeLoop(e) {
        this.player.loop = !this.player.loop;
        e.target.classList.toggle('is-loop');
      }


      //音量调整
      changeVolume(e) {
        let ratio = Number(e.target.value) / 100;
        this.volume = ratio;
      }

      chageMuted(e) {
        this.player.muted = !this.player.muted;
        e.target.classList.toggle('is-muted');
      }

      //存储观看信息 到本地存储
      setVideoInfo() {
        //视频src=>ID 播放时间
        if (!this.canPlay) {
          //视频准备好了播放的情况下才存储
          return false;
        }
        this.storage.setStorage({
          [this.player.src]: this.player.currentTime
        })

      }
    }

    function padLeft(num) {
      return String(num)[1] && String(num) || '0' + num;
    }

    const myPlay = new MyVideo();
  </script>
</body>

</html>
vue+elementUI走马灯组件+html <video>实现轮播视频,并自定义视频播放按钮完整demo 效果: 代码: html部分: <el-carousel :interval="5000" arrow="always" :autoplay="autoplay" :indicator-position="autoplay?'':'none'" @change="getIndex"> <el-carousel-item v-for=". 阅读详情

相关推荐

移动端自定义video播放控件controls(带播放暂停,进度条拖拽)

效果图如下 html结构部分 <div class="player"> <video id="video" muted poster="images/video_poster.png"> <source src="https://video.pearvideo.com/mp4/adshort/20190702/cont-1572578-14079299_adp...

萌面怪瘦的博客 8608

video 自定义视频播放控件

自定义视频播放控件,控件位置可随意放置

细节怪的博客 1万+

微信小程序video自定义control

1.背景: 有些时候需要用到video自定需求,可以参考如下案例 2.思路 2.1 把原生的controls(底部的控制,进度条,暂停播放)隐藏掉,然后自己重写controls: 2.2 把原生的show-fullscreen-btn(全屏,退出全屏)隐藏掉,并重写; 2.3 定义bindplay(播放),bindpause(暂停),bindended(播放完毕),bindtimeupdate(更新播放时间,在拖动进度条时需要用到),一一通过代码实现即可 3.代码: 3.1wxml <v

hangGe0111的博客 4416

给video视频自定义添加中间播放按钮

gei实现效果:视频中间添加播放按钮,且鼠标移上去有波浪动画效果,点击可以控制视频播放 播放按钮可以使用盒子绝对定位在视频中间,当点击时触发video的播放事件,同时让盒子隐藏。 <div class="video-right"> <video controls @pause="videoPause" @play="videoPlay" ref="myVideo..

cpc980209的博客 1万+

微信小程序 - 最新详细实现 <video> 视频组件自定义封面及播放按钮,给 video 视频播放组件加上封面图、封面标题、封面描述文字、自定义的播放按钮、DIY 封面等(详细示例源码)

微信小程序video封面,微信小程序video视频组件,微信小程序实现video封面图封面文字,微信小程序视频组件video怎么加封面图,微信小程序:video标签默认显示视频的第一帧作为封面,微信小程序Video组件实现视频、自定义播放按钮、封面图、封面图文字demo,微信小程序-实现视频组件自定义封面及播放按钮,给video视频播放组件加上封面图、封面标题、封面描述文字、自定义的播放按钮、DIY封面等(详细示例源码)

🏆 前端领域优质创作者 8904

CSP-J 初赛模拟卷1 题解

只有一棵子树有后继,其他的都是叶结点才能保证树的深度最大,此时还剩(n-5)个结点,最后加上2,得到(n-3),即为答案。题解:先修改p的指针域,让它的左指针域指向q,然后再让q的右指针域赋值给p的右指针域,再然后修改q的右指针域使其指向p,最后需要改变的指针域就是原先q结点的后继节点的左指针域内容。设n个元素的入栈序列是1,2,3,...,n,出栈序列为p1,p2,...,pn,若p1=n,则pi(1≤i≤n)的值为(1)输入的三个数中,第二个数应是[0,11]上的整数,否则会出现数组越界的问题。

Sat77GryHp_Pro的博客 2805

video-js 库使用 自定义组件

video-js 库使用 自定义组件 video-js 库 原始版的库:github/videojs vue 封装过的组件:npm/vue-video-player 这是一个非常棒的播放器,还兼容 hls 的直播流(m3u8)格式的等,还支持自定义组件,基本上满足播放器的很多功能了。 如果想了解直播的可以看下以前的文章 vue 项目进行直播视频 vue-video-player 后面更多会说自定义组件 说一说我的遇到的坑: 本来用播放器播放直播流 OK 了,可是 UI 和我说,播放器在回放的时候,希望像普

Jioho的博客 4214

内网(极空间)搭建gitlab跳板机转发端口及域名配置

然后,回头尝试用内网地址+15022 clone,成功,用公网的ip+15222 clone失败,那就是定位到时nginx转发的问题了。首先想到的就是 git clone是通过ssh的22端口进行下载的,那就需要打通22端口,则又配置22端口的nginx转发。然后,我通过ssh命令,做一个端口转发,以实现内网穿透,将服务端口链接到跳板机上。然后穿透到阿里云服务器跳板机的端口,只能内网访问,需要用nginx做个转发,才能用公网ip进行访问。然后,如上,我的80端口,映射15080,22端口映射15022。

God丶Davide的博客 6074

video.js 自定义使用

v ideo.js 直接使用 自定义控制条和样式 弹幕相关 plugin写法 video.js 是开源插件,据说甚至可以集合到gitbook上note: 一个需要注意的点是下载下来的demo.html直接右键浏览器是打不开的,需要用iis或者nginx 或者beego这些服务端的玩意加载后,在前端浏览器才能看到视频页面。参考文章: HTML5视频播放器Video.Js

software1的专栏 5万+

GEOPHYSICS 投稿避坑指南:从格式规范到双盲评审的实战解析

本文详细解析了GEOPHYSICS期刊投稿的全流程避坑指南,从格式规范、数据声明到双盲评审的实战策略。特别强调了数学公式排版、图表制作标准以及投稿系统的隐藏关卡,帮助作者避免常见错误,提升投稿成功率。

weixin_30606461的博客 236

鲸鱼优化算法(WOA)与门控循环单元(GRU)结合的预测模型(WOA-GRU)及其Python和MATLAB实现

Python和MATLAB的实现均突出模型结构和优化过程。2. **全局搜索与局部搜索结合**:WOA在寻优时,既有全局搜索的能力,又具备局部精准搜索的能力,能有效避免陷入局部最优解。2. **简化结构**:与长短期记忆(LSTM)相比,GRU的结构更为简化,避免了多层细胞结构,提高了计算效率。4. **使用WOA进行优化**:通过WOA迭代优化GRU模型中的参数,如学习率、批量大小和GRU单元的权重。3. **良好的表现**:GRU在多个时序数据序列的预测任务中表现优异,特别是在较短的数据序列中。

qq_45441438的博客 1324

css video 样式,css自定义video播放器样式的方法

css自定义video播放器样式的方法发布时间:2020-09-14 14:46:29来源:亿速云阅读:58作者:小新css自定义video播放器样式的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!DIY本文基于HTML5 Video API,自定义Web视频播放器样式。其实吧,原生的video 标签样式挺好看...

weixin_39715834的博客 5978

四款办公Agent实测对比:WorkBuddy、千问办公、库库AI、豆包工作怎么选

AI Agent是一种能感知环境、自主决策并执行动作的智能系统,其核心在于工具调用、状态管理与错误恢复构成的执行闭环。在办公场景中,任务边界清晰、容错率高、重复性强,使Agent成为最容易落地的方向。通过调用本地文件、脚本或办公套件,Agent能自动完成文件批量处理、文档摘要、会议纪要等重复劳动,显著提升工作效率。目前WorkBuddy、千问办公、库库AI、豆包工作等产品分别从本地操作、办公套件嵌入、知识处理、轻量助手等路线切入,用户可根据自身场景选择。

weixin_29052717的博客 521

video 元素自定义 controls 控件以及常用事件、方法

当 video 标签添加上 controls 属性时,页面上会显示出所有的控制组件。若有些组件不需要只需要在 css 中设置相关属性把它隐藏掉即可。可以在开始标签和结束标签之间放置文本内容,这样老的浏览器就可以显示出不支持该标签的信息。

来杯卡布奇诺的博客 1万+

工艺边与定位孔设计经验规则总结

工艺边是在SMT焊接时,为了PCB和导轨接触预留的PCB边。工艺边和PCB的接触部分一般需要开槽,或者使用邮票孔,以方便后期去除工艺边。

fydar的博客 1984

2023年全国职业院校技能大赛“信息安全管理与评估”-真题——赛题题目+答案解析

2023年全国职业院校技能大赛“信息安全管理与评估”-真题——赛题题目+答案解析

君逍遥o 6004

H5自定义video播放控件,播放暂停使用图标

大家都知道vedio的contorls属性可以将video的控件显示出来,包括播放、暂停、进度条、声量控制、全屏显示等。但是出于需求,往往需要将某些控件外形变成我们想要图标(但功能一样),而不是全部使用vedio自带的控件图标。 下面这个例子,我将隐藏video自带的播放按钮,使用自定义的播放、暂停图标作为控件,下面这个例子是从awesome图标库下载的图片,大家自行选择! 播放图标下载地址为:play-circle – Font Awesome 中文网 为了读者能够一目了然地了解制作效果,下面展示g

calm_programmer的博客 7884

使用Clumsy和Process Explorer定位软件高CPU占用问题

使用弱网模拟工具Clumsy和进程查看工具Process Explorer定位软件高CPU占用问题。

dvlinker的技术专栏 5706

自定义video标签进度条

<!doctype html> <html> <head> <meta charset="utf-8"> <title>短视频</title> <style lang="en"> html, body{ ...

dengzhuanhu2252的博客 1315

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

实现video自定义功能

效果图片 HTML代码 <div class="video_player"> <video src="res/birds.mp4"></video> <div class="menu"> <div class="play">播放</div> <div class="time">00:00/00:00</div> .

Mr_box_的博客 806

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

H5自定义video功能与样式处理

H5的video非常简单,方便,有时我们可能需要自己来设置样式来自定义的video,自定义的话我们需要对功能进行一些处理,这里常用的功能几乎是都用到了,第一次练习代码很累赘,之后会慢慢改进。 常用的一些 video API "视频播放":video.play(); "视频暂停播放":video.pause(); "视频地址":video.currentSrc; "视频总时长":vide...

weixin_30568715的博客 1730

JS 用CANVAS自定义VIDEO播放器

为了实现客户定制统一风格视频播放器,HTML网页可以借助CANVAS进行自定义VIDEO绘制

qq_31042143的博客 3454

微信小程序之自定义video组件

自定义video 小程序项目中使用到video组件,并且根据需求自定义播放、进度条和全屏按钮,本次需求比较简单,没有涉及试看,指定时长等功能,仅是简单的播放,记录一下,以防遗忘。贴下video组件的文档链接:video 大概效果: 本文中用到的一些比较重要的属性和API - duration:指定视频时长(总时长) - controls:是否显示默认播放控件(播放/暂停按钮、播放进度、时间) - poster:视频封面 - bindended:当视频播放到末尾触发 - bindtimeupdat

Leo_xian的博客 5110

小程序 uni-app video 自定义控制条

本来不想自定义video的控制条的,感觉不同机型,不同操作系统会有bug,肯定不如自带的好,不过,因为iPhone11或是iPhoneX下面的横线,导致,一想拖动进度条,就切换屏幕,video自带的控制条还不能控制在屏幕的位置。没办法,小白也得上手了。 先放两张真机截图: <video @pause="pause" @play="contrPlay" v-if="reFresh" class="video-class" :src="recordUrl" style="...

maxiaole_z的博客 9135

html video 修改封面,html5自定义video标签的海报与播放按钮功能

一、问题1.默认播放按键不好看2.设置自定义封面图以上这两点都想自定义二、思路1.使用div把video标签盖住2.div中显示自定义的海报图片与按钮三、步骤分解1.海报图片作为div的背景注:无论是横图还是竖图,都希望按原比例显示在div内css:.yourDiv{background-color: black;height:20em;background-image: url('./image...

weixin_29864813的博客 1446
上一篇: Promise 对象
下一篇: 读取文件进度条
喵_美
博客等级 码龄11年 445粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值