• 基于flv.js自定义播放器UI界面


    公司需要播放flv格式播放器,所以基于flv.js写了个带UI的播放器,可支持MP4和flv格式,需要的可以直接复制,播放器界面如下,鼠标hover状态,以及播放中下边界显示播放进度

     
    1.引入
    首先将后边代码保存作为组件引入
     
      <FlvVideo   :VideoUrl="defintion"  VideoCode="flv"> </FlvVideo>
    import FlvVideo from "~/components/flv";
    export default {
      components:{
        FlvVideo
      },
    data(){
    return{
    defintion:[]

    }
    } 。。。。。 }

    2.设置清晰度

     
     this.defintion=[//设置不同清晰度,以及清晰度按钮文本
                  {url:this.urls+'?definition=LD&videoType=flv',leavel:'高清'},
                  {url:this.urls+'?definition=SD&videoType=flv',leavel:'超清'}
                  ]
     
    //将一下代码保存为flv.vue
    
    
    <template>
      <!-- create by zzh 2020-6-20 23:18 -->
      <div class="video-box" :style="{position:isFixed}">
        <!--video 盒子-->
        <div class="video-box-body" @mousemove="Enter" @mouseenter="Enter" @click="Enter">
          <div class="loader" v-show="isLoading" title="2">
            <svg
              version="1.1"
              id="loader-1"
              x="0px"
              y="0px"
              width="100px"
              height="100px"
              viewBox="0 0 50 50"
              style="enable-background:new 0 0 50 50;"
              xml:space="preserve"
            >
              <path
                fill="#000"
                d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z"
                transform="rotate(110.097 25 25)"
              >
                <animateTransform
                  attributeType="xml"
                  attributeName="transform"
                  type="rotate"
                  from="0 25 25"
                  to="360 25 25"
                  dur="0.6s"
                  repeatCount="indefinite"
                />
              </path>
            </svg>
            <div class="load-msg">加载中,请稍后....</div>
          </div>
          <canvas v-show="isCanvas" class="video-body" id="canvas">您的浏览器不支持canvas</canvas>
          <video
            v-show="!isCanvas"
            class="video-body"
            @ended="ended($event)"
            @error="error($event)"
            @loadstart="loadstart($event)"
            @canplay="canplay($event)"
            @seeking="seeking($event)"
            @seeked="seeked($event)"
            @timeupdate="timeupdate($event)"
            id="videoBody"
          >您的浏览器不支持video</video>
          <!--控制条盒子-->
          <div class="video-control" v-if="isLoaded" v-show="isShowControl">
            <div class="pull-left fontzero control-leftview">
              <!--刷新键-->
              <!-- <div class="control-btn loadbtn"></div> -->
              <!--暂停/播放键-->
              <div class="control-btn playbtn" :class="{pausebtn:isPlay}" @click="play"></div>
            </div>
            <div class="pull-left fontzero progress-box">
              <div class="progress-box-body">
                <!--播放时长-->
                <div class="current-time pull-left">{{currentDuration|initTimeLength}}</div>
                <div class="durationbar-box pull-left">
                  <!--总视频长度进度条-->
                  <div class="durationbar">
                    <!--缓冲进度条-->
                    <div class="bufferbar" :style="{getBuffPrecent+'%'}"></div>
                    <!--正在播放进度条-->
                    <div class="currentbar" :style="{(currentDuration/duration)*100+'%'}"></div>
                    <div
                      class="drawbar"
                      :class="{drawbar_active:isdrawbar_active}"
                      :style="{left:(currentDuration/duration)*100+'%',transform: 'scale(2) rotateZ('+(currentDuration/duration)*4*720+'deg)'}"
                    ></div>
                    <input
                      class="bar-input"
                      @mouseleave="removeDrawbar"
                      @mouseenter="setDrawbar"
                      @mouseup="sliderUp()"
                      @input="slider($event,'continue')"
                      @change="slider($event,'')"
                      type="range"
                      min="0"
                      max="100"
                      :value="getCurrentDurationPercent"
                    />
                  </div>
                </div>
                <!--总时长-->
                <div class="duration-time pull-left">{{duration|initTimeLength}}</div>
              </div>
            </div>
            <div class="pull-left fontzero control-rightview">
              <!-- 清晰度切换 -->
              <div class="defintion-wrap" v-show="isShowDefintion">
                <div
                  class="leavel"
                  v-for="(item,index) in VideoUrl"
                  :key="item.leave"
                  :class="{isActive:defintion==item.leavel}"
                  @click="chooseDefintion(item.leavel,index)"
                >{{item.leavel}}</div>
              </div>
              <div class="defintion" @click="openDefintion">{{defintion}}</div>
              <!-- 倍数播放 -->
              <div class="speed-wrap" v-show="isShowSpeed">
                <div
                  class="leavel"
                  v-for="item in Speed"
                  :key="item"
                  @click="chooseSpeed(item)"
                  :class="{isActive:speed==item}"
                >X{{item.toFixed(1)}}</div>
              </div>
              <div class="speed" @click="openSpeed">X{{speed}}</div>
              <!--音量键-->
              <div class="control-btn mutedbtn" :class="{muted:isMuted}" @click="setMute()"></div>
              <div class="volumn-btn-wrap">
                <input
                  class="volume-input"
                  :style="{'background':'linear-gradient(to right, #a7bfe8, #6190e8 ' + volume + '%, #ebeff4)' }"
                  @input="setvolume($event)"
                  @change="setvolume($event,'end')"
                  type="range"
                  min="0"
                  max="100"
                  v-model="volume"
                />
                <div class="volumn-btn" :style="{left:(volume)+'px'}"></div>
              </div>

              <!--全屏键-->
              <div class="control-btn fullscreenbar" @click="fullScreen"></div>
              <!-- <div class="control-btn mime" @click="switchMime()">{{mime}}</div> -->
            </div>
          </div>
          <div class="video-progress" v-if="ifisShowControl" v-show="!isShowControl">
            <div class="video-progress-current" :style="{(currentDuration/duration)*100+'%'}"></div>
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          flvSdkPath: "https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js",
          mime: "flv",
          currentDuration: "0",
          currentDurationTemp: 0,
          duration: "1",
          getBuffPrecent: "",
          isPlay: false,
          refDom: null,
          flv_player_instance: null,
          volume: 0,
          canvas: null,
          context: null,
          isCanvas: false,
          isShowControl: false,
          isLoading: false,
          isdrawbar_active: false,
           0,
          height: 0,
          isFixed: "relative",
          timer: null,
          speed: 1,
          defintion: "",
          isShowSpeed: false,
          isShowDefintion: false,
          controlTimer: null,
          getCurrentDurationPercent: 0,
          isNotDrag: true, //标志是否拖动中,快进快退中避免更新进度条
          flvVideoCode: "flv",
          isLoaded: false,
          defintionTimer: null,
          speedTimer: null,
          isMuted: false,
        };
      },
      head() {
        return {};
      },
      props: {
        // VideoUrl: {
        //   type: String,
        //   default:
        //     "http://store.91yunshi.com/storage/videoAuth/gaugua/41175fe7fdc74354a8d99a3f7aa1457d.mp4?videoType=flv&_t=1592535251776"
        // },
        Speed: {
          type: Array,
          default() {
            return [0.5, 1.0, 1.5, 2];
          },
        },
        ifisShowControl: {
          type: Boolean,
          default: true, //只支持flv或MP4
        },
        VideoCode: {
          type: String,
          default: "flv", //只支持flv或MP4
          validator: function (value) {
            // 这个值必须匹配下列字符串中的一个
            return ["flv", "mp4"].indexOf(value) !== -1;
          },
        },
        VideoUrl: {
          type: Array,
          default() {
            return [
              // {
              //   url:
              //     "http://store.91yunshi.com/storage/videoAuth/gaugua/41175fe7fdc74354a8d99a3f7aa1457d.mp4?videoType=flv&_t=1592535251776",
              //   leavel: "高清"
              // },
              // {
              //   url:
              //     "http://store.91yunshi.com/storage/videoAuth/gaugua/41175fe7fdc74354a8d99a3f7aa1457d.mp4?videoType=flv&_t=1592535251776",
              //   leavel: "超清"
              // },
              // {
              //   url:
              //     "http://store.91yunshi.com/storage/videoAuth/gaugua/41175fe7fdc74354a8d99a3f7aa1457d.mp4?videoType=flv&_t=1592535251776",
              //   leavel: "蓝光"
              // }
            ];
          },
        },
      },
      watch: {
        VideoUrl: {
          handler(newVal, old) {
            this.reloadUrl();
          },
          deep: true,
        },
      },
      filters: {
        initTimeLength(timeLength) {
          let result = parseInt(timeLength);
          let h =
            Math.floor(result / 3600) < 10
              ? "0" + Math.floor(result / 3600)
              : Math.floor(result / 3600);
          let m =
            Math.floor((result / 60) % 60) < 10
              ? "0" + Math.floor((result / 60) % 60)
              : Math.floor((result / 60) % 60);
          let s =
            Math.floor(result % 60) < 10
              ? "0" + Math.floor(result % 60)
              : Math.floor(result % 60);

          return `${h}:${m}:${s}`;
          // //根据秒数格式化时间
          // timeLength = parseInt(timeLength);
          // var second = timeLength % 60;
          // var minute = (timeLength - second) / 60;
          // return (
          //   (minute < 10 ? "0" + minute : minute) +
          //   ":" +
          //   (second < 10 ? "0" + second : second)
          // );
        },
        // speedFilter(val){
        //   console.log(val);
        //   let num = parseInt(val)
        //   return num.toFixed(1)
        // }
      },
      methods: {
        switchMime() {
          if (this.mime == "flv") {
            this.mime = "mp4";
          } else {
            this.mime = "flv";
          }
          this.$emit("mime", this.mime);
        },
        setDrawbar() {
          this.isdrawbar_active = true;
        },
        removeDrawbar() {
          this.isdrawbar_active = false;
        },
        Enter() {
          clearTimeout(this.controlTimer);
          this.isShowControl = true;
          this.controlTimer = setTimeout(() => {
            this.isShowControl = false;
          }, 5000);
        },
        openDefintion() {
          //打开清晰度切换容器
          clearTimeout(this.defintionTimer);
          this.isShowDefintion = true;
          this.defintionTimer = setTimeout(() => {
            this.isShowDefintion = false;
          }, 3000);
        },
        chooseDefintion(defintion, index) {
          localStorage.setItem("flv_defintion", index);
          localStorage.setItem(
            "flv_defintion_currenttime",
            this.refDom.currentTime
          );
          //选择清晰度
          this.defintion = defintion;
          this.isShowDefintion = false;
          this.reloadUrl();
        },
        reloadUrl() {
          this.flv_destroy();
          this.initPlay();
        },
        openSpeed() {
          //打开播放速度容器
          clearTimeout(this.speedTimer);
          this.isShowSpeed = true;
          this.speedTimer = setTimeout(() => {
            this.isShowSpeed = false;
          }, 3000);
        },
        chooseSpeed(speed) {
          //选择播放速度
          this.refDom.playbackRate = speed;
          this.speed = speed;
          this.isShowSpeed = false;
        },
        setvolume(e, isend) {
          //设置音量
          let dom = e.target;
          if (isend == "end" && this.isMuted) {
            this.refDom.muted = false;
            this.isMuted = false;
          }
          this.refDom.volume = dom.value / 100;
          localStorage.setItem("fly_volume", dom.value / 100);
          this.volume = dom.value;
        },
        slider(e, type) {
          //进度滑动设置
          let dom = e.target;
          this.currentDuration = this.currentDurationTemp =
            (Number(dom.value) * this.duration) / 100;
          if (type == "continue") {
            this.refDom.pause();
          } else {
            this.refDom.currentTime = this.currentDuration;
          }
        },
        sliderUp() {
          this.refDom.currentTime = this.currentDurationTemp;
          // this.isNotDrag=true;
          //  console.log( this.isNotDrag);
          this.refDom.play();
        },
        init(videoItem) {
          this.isLoaded = false; //播放器数据初始化能播放后再显示UI页面
          let url = "";
          this.refDom = document.getElementById("videoBody");
          if (!!!videoItem) return;
          url = videoItem.url;
          console.log(url);
          //flv播放器初始化
          window.cancelAnimationFrame(this.timer);
          if (flvjs.isSupported()) {
            this.flv_player_instance = flvjs.createPlayer(
              {
                seekType: "range",
                type: this.flvVideoCode,
                url: url,
                isLive:false
              },
              {
                enableWorker: true,
                lazyLoad: false,
                lazyLoadMaxDuration: 20 * 60,
              }
            );
            this.defintion = videoItem && videoItem.leavel;
            this.flv_player_instance.attachMediaElement(this.refDom);
            this.flv_player_instance.load(); //加载
            this.flv_player_instance.play();
            this.flv_player_instance.on("error", (err) => {
              // console.log('err', err);
              if (err == "MediaError") {
                if (this.flvVideoCode == "flv") {
                  //如果是格式错误,尝试切换格式播放
                  this.flvVideoCode = "mp4";
                  console.warn("尝试切换mp4格式播放");
                } else {
                  console.warn("尝试切换flv格式播放");
                  this.flvVideoCode = "flv";
                }
                this.reloadUrl();
              }
            });
          } else {
            this.refDom.src = url;
          }
        },
        flv_destroy() {
          if (this.flv_player_instance) {
            this.flv_player_instance.pause();
            this.flv_player_instance.unload();
            this.flv_player_instance.detachMediaElement();
            this.flv_player_instance.destroy();
            this.flv_player_instance = null;
          }
        },
        setMute() {
          if (!this.refDom.muted) {
            this.refDom.muted = true;
            this.isMuted = true;
          } else {
            this.refDom.muted = false;
            this.isMuted = false;
          }
        },
        canplay(e) {
          this.isLoaded = true;
          let currentTime = localStorage.getItem("flv_defintion_currenttime"); //保存上次进度,切换清晰度的时候还原进度
          //资源可以播放
          let dom = e.target;
          if (!!currentTime) {
            dom.currentTime = currentTime;
            localStorage.removeItem("flv_defintion_currenttime");
          }
          this.duration = dom.duration || 1;
          this.currentDuration = dom.currentTime || 0;
          dom.volume = localStorage.getItem("fly_volume") || 0.5;
          this.volume = dom.volume * 100;
          this.speed = dom.playbackRate.toFixed(1);
          dom.play();
          this.isLoading = false;
          this.$emit("isplay", true);
        },
        getCanvasInit() {
          //canvas初始化
          this.canvas = document.getElementById("canvas");
          this.context = canvas.getContext("2d");
          this.canvas.width = document.body.clientWidth;
          this.canvas.height = document.body.clientHeight;
          this.drawCanvas();
        },
        drawCanvas() {
          //绘制视频到canvas
          this.context.drawImage(
            this.refDom,
            0,
            0,
            this.canvas.width,
            this.canvas.height
          ); //绘制视频
          this.timer = window.requestAnimationFrame(this.drawCanvas);
        },
        play() {
          //播放暂停
          if (this.refDom.paused) {
            this.refDom.play();
            this.isPlay = false;
          } else {
            this.refDom.pause();
            this.isPlay = true;
          }
        },
        fullScreen() {
          if (this.isFixed == "fixed") {
            //如果全屏退出全屏
            this.isFixed = "relative";
            // this.isCanvas = false;
            // window.cancelAnimationFrame(this.timer);
          } else {
            this.isFixed = "fixed";
            // this.isCanvas = true;
            // this.getCanvasInit();
          }
        },
        ended(e) {
          this.$emit("flvEnded", true);
        },
        seeking(e) {
          // console.log(e);
          this.isLoading = true;
        },
        seeked(e) {
          this.isLoading = false;

          // console.log(e);
        },
        error(e) {
          let err = e.target.error;
          console.error(err);

          if (err.code == 4) {
            //error.code; //1.用户终止 2.网络错误 3.解码错误 4.URL无效
            if (this.flvVideoCode == "flv") {
              //如果是格式错误,尝试切换格式播放
              this.flvVideoCode = "mp4";
              console.warn("尝试切换mp4格式播放");
            } else {
              console.warn("尝试切换flv格式播放");
              this.flvVideoCode = "flv";
            }
            this.reloadUrl();
          }
          this.isLoading = false;
        },
        loadstart() {
          this.isLoading = true;
        },
        timeupdate(e) {
          //播放进度更新回调
          let dom = e.target;
          // 视频时长
          this.duration = dom.duration || 1;
          // currentTime 当前播放时长
          this.currentDuration = dom.currentTime;
          //当前缓冲进度时长结束位置
          let buffLength = dom.buffered.length;
          if (buffLength != 0) {
            var currentBuffer = dom.buffered.end(buffLength - 1);
            var percentage = (100 * currentBuffer) / this.duration;
            this.getBuffPrecent = percentage;
          }
          if (this.isNotDrag) {
            this.getCurrentDurationPercent =
              (this.currentDuration / this.duration) * 100;
          }
        },
        initPlay() {
          let defintion = localStorage.getItem("flv_defintion");
          if (!!defintion) {
            //如果本地保存了清晰度自动选择之前清晰度,否则加载第一个

            this.insertScriptTag(() => {
              this.init(this.VideoUrl[defintion]);
            });
          } else {
            this.insertScriptTag(() => {
              this.init(this.VideoUrl[0]);
            });
          }
        },
        insertScriptTag(cb) {
          const _this = this;
          let playerScriptTag = document.getElementById("playerScriptTag");
          // 如果这个tag不存在,则生成相关代码tag以加载代码
          if (playerScriptTag === null) {
            playerScriptTag = document.createElement("script");
            playerScriptTag.type = "text/javascript";
            playerScriptTag.id = "playerScriptTag";
            let s = document.getElementsByTagName("head")[0];
            playerScriptTag.onload = playerScriptTag.onreadystatechange = function () {
              if (
                !this.readyState ||
                this.readyState === "loaded" ||
                this.readyState === "complete"
              ) {
                cb && cb();
                playerScriptTag.onload = playerScriptTag.onreadystatechange = null;
              }
            };
            playerScriptTag.src = this.flvSdkPath;
            s.appendChild(playerScriptTag);
          } else {
            cb && cb();
          }
        },
      },
      mounted() {
        // console.log(this.VideoUrl);
        if (this.VideoUrl.length == 0) {
          return new Error("未输入地址");
        }
        this.flvVideoCode = this.VideoCode;
        this.insertScriptTag(() => {
          this.initPlay();
        });
      },
    };
    </script>
    <style scoped>
    /*video样式*/
    .video-box {
      top: 0;
      left: 0;
      overflow: hidden;
      background: #000;
       100%;
      height: 100%;
      z-index: 999;
    }
    .video-box-body {
      position: relative;
       100%;
      height: 100%;
      overflow: hidden;
    }
    .video-body {
      position: absolute;
      left: 0;
      top: 0;
       100%;
      height: 100%;
      z-index: 15;
    }
    #canvas {
       80%;
      left: 10%;
    }
    /*控制条样式*/
    .video-control {
      display: flex;
      position: absolute;
       100%;
      height: 60px;
      padding: 5px;
      line-height: 50px;
      background: rgba(0, 0, 0, 0.5);
      box-shadow: 0 1px 15px 15px rgba(0, 0, 0, 0.5);
      transition-duration: 300ms;
      z-index: 999;
      left: 0;
      bottom: 0;
    }
    .control-leftview {
      display: flex;
      position: relative;
      z-index: 5;
       120px;
    }
    .control-btn {
      display: inline-block;
       25px;
      height: 25px;
      background: rgba(256, 256, 256, 0.5);
      cursor: pointer;
    }
    .control-leftview .control-btn {
      margin-right: 10px;
    }
    .progress-box {
       85%;
      height: 50px;
      padding-right: 20px;
    }
    .progress-box-body {
      display: flex;

       100%;
      height: 100%;
    }
    .current-time,
    .duration-time {
       60px;
      text-align: center;
      color: #fff;
    }
    .current-time {
      margin-right: -60px;
      position: relative;
      z-index: 5;
    }
    .duration-time {
      margin-left: -60px;
      position: relative;
      z-index: 5;
    }
    .durationbar-box {
      position: relative;
       100%;
      padding: 0 70px;
    }
    .durationbar {
       100%;
      height: 6px;
      margin-top: 23px;
      background: #fff;
      border-radius: 50px;
      position: relative;
    }
    .bufferbar,
    .currentbar {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
       0;
      background: rgba(0, 0, 0, 0.3);
      border-radius: 50px;
      z-index: 5;
      cursor: pointer;
    }
    .currentbar {
      background: linear-gradient(to right, #a7bfe8, #6190e8);
      z-index: 10;
    }
    .drawbar {
      position: absolute;
      background: #fff;
       20px;
      height: 20px;
      left: 0;
      top: -5px;
      z-index: 10;
      margin-left: -4px;
      border-radius: 50px;
      cursor: pointer;
      background-color: transparent;
      background-image: url("../assets/image/thumbs-sprite.png");
      background-position: 0 0;
      background-size: cover;
      transform: scale(1.9) rotateZ(10deg);
    }
    .drawbar_active {
      background-position: 100% 0px;
    }
    .control-rightview {
      cursor: pointer;
      position: relative;
       460px;
      z-index: 5;
    }
    .speed {
      display: inline-block;
       40px;
      color: #fff;
      font-size: 16px;
    }
    .defintion {
      display: inline-block;
      color: #fff;
      font-size: 14px;
       40px;
    }
    .isActive {
      color: coral;
    }
    .leavel {
      cursor: pointer;
    }
    .speed-wrap {
      position: absolute;
      bottom: 50px;
      left: 44px;
      background: rgba(0, 0, 0, 0.5);
      color: #fff;
      padding: 0 10px;
      border-radius: 6px;
      line-height: 30px;
      font-size: 16px;
    }
    .defintion-wrap {
      position: absolute;
      bottom: 50px;
      left: -10px;
      background: rgba(0, 0, 0, 0.5);
      color: #fff;
      padding: 0 10px;
      border-radius: 6px;
      line-height: 30px;
      font-size: 16px;
    }
    .control-rightview .control-btn {
      margin-left: 10px;
      vertical-align: middle;
    }
    .control-leftview .control-btn:last-child,
    .control-rightview .control-btn:first-child {
      margin: 0;
    }
    .control-btn.loadbtn {
      /* background: url(../img/load.png) no-repeat center; */
      background-size: 100%;
    }
    .control-btn.playbtn {
       50px;
      height: 50px;
      background: url("../assets/image/pause.png") no-repeat center;
      background-size: 100%;
    }
    .control-btn.playbtn.pausebtn {
      background: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZmZmZmZmIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik04IDV2MTRsMTEtN3oiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+Cg==")
        no-repeat center;

      background-size: 100%;
    }
    .control-btn.mutedbtn {
      background: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZmZmZmZmIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0zIDl2Nmg0bDUgNVY0TDcgOUgzem0xMy41IDNjMC0xLjc3LTEuMDItMy4yOS0yLjUtNC4wM3Y4LjA1YzEuNDgtLjczIDIuNS0yLjI1IDIuNS00LjAyek0xNCAzLjIzdjIuMDZjMi44OS44NiA1IDMuNTQgNSA2Ljcxcy0yLjExIDUuODUtNSA2LjcxdjIuMDZjNC4wMS0uOTEgNy00LjQ5IDctOC43N3MtMi45OS03Ljg2LTctOC43N3oiLz4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KPC9zdmc+Cg==")
        no-repeat center;
      background-size: 100%;
    }
    .control-btn.muted {
      background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACZklEQVR4Xu2avy4FQRTGvxM9SomSChGVRCehUQkJiV6vEjrUXkNF4s8TeAQVFRoPIPECnxyZm6yxu7PuWHd2z2xzczN39u73m++c+bNHYPwS4/qRAWQHGCeQQ8C4AUaTBEluAFgGcCEiL6MchH8NAZIzAI4B7DvRNyKybQIAyQMnfqooWET+dRB82K3/Ocl1AEcA9PPH1VsAJHWk1e468pVXLwGQ1BhX8RrztVevAJBccXbfDAkftPcCAMlxJ1xjfaypeP1d5wGQ3HN2X/yN8KQcQHIHwAmA+WFExPQZuQNIqvDTGBExfVMA8ABgKUZETN8UADBGQGzfDGDUS2GS2QGxNo7pXxcChdlpGsA9gMPQ9tntOM8BrAF4BXArImdVzyipOqBidnoEsCsiT2WCSM4BuCyZzrXPVelmLGEAVbNTKYQa8ar7UUQWugbgHcBkhXW/QQiI11t8iMhE1wBcA9iqyS9fEFx7me2LXStPnlLOAbqVvgssz5+dytkAqM2q5JksABXUwNqhCag2aX7tRlNNggNlERCC4jsBYEgnNBLfGQAFCJoT6uJdf6p5QWO+dK3gx0zyIeCFgk0AQ+SB/oTAEOIHpmkEIekQiBDfGEKyANyuzu5CiKT5pbD5zZD57XDZcb2dAxG3+hu8sLF3JBba5v1Ve7LT4F8JDN0nAyBp/tWY7ZejXra193o8lCRC7b0okAiJDLWbLpEpwjFbJOU7xGyZnOcGu4WSHgibpbIlYWGzWNpzg91yeQ/Eqvv+Fqr4CE3Bse2tl8vHPmDb/TOAtgmnfv/sgNRHqO3nyw5om3Dq9/8EUtNyUHSPJr8AAAAASUVORK5CYII=")
        no-repeat center;
      background-size: 100%;
    }
    .control-btn.fullscreenbar {
      background: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZmZmZmZmIiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4KICAgIDxwYXRoIGQ9Ik03IDE0SDV2NWg1di0ySDd2LTN6bS0yLTRoMlY3aDNWNUg1djV6bTEyIDdoLTN2Mmg1di01aC0ydjN6TTE0IDV2MmgzdjNoMlY1aC01eiIvPgo8L3N2Zz4K")
        no-repeat center;
      background-size: 100%;
    }
    .control-btn.mime {
      line-height: 25px;
      background: none;
      color: #fff;
    }
    .bar-input {
      position: absolute;
      height: 100%;
      left: 0;
      right: 0;
      margin: auto;
       100%;
      opacity: 0;
      z-index: 999;
      cursor: pointer;
    }
    .volumn-btn-wrap {
      position: relative;
      display: inline-block;
       120px;
    }
    /* .volumn-btn-slider{
      
    } */
    .volumn-btn {
      position: absolute;
      left: 0;
      top: 20px;
      height: 20px;
       20px;
      transform: translateY(0px);
      background: #fff;
      border-radius: 15px;
      border: 5px solid #6190e8;
      z-index: -1;
    }
    .volume-input {
      height: 100%;
       100%;
      /* opacity: 0; */
      z-index: 999;
      cursor: pointer;
    }
    .loader {
       140px;
      height: 140px;
      /* border: 1px solid red; */
      text-align: center;
      position: absolute;
      top: calc(50% - 70px);
      left: calc(50% - 70px);
      padding-top: 15px;
      z-index: 9999;
      background-color: rgba(0, 0, 0, 0.5);
      border-radius: 5px;
    }

    #loader-1 {
       60px;
      height: 60px;
    }
    svg path,
    svg rect {
      fill: #17a085;
    }
    .load-msg {
      height: 50px;
      line-height: 50px;
      color: #fff;
      font-size: 13px;
      /* margin-top: 20px; */
    }
    .volume-input {
      /*-webkit-box-shadow: 0 1px 0 0px #424242, 0 1px 0 #060607 inset, 0px 2px 10px 0px black inset, 1px 0px 2px rgba(0, 0, 0, 0.4) inset, 0 0px 1px rgba(0, 0, 0, 0.6) inset;*/
      -webkit-appearance: none; /*去除默认样式*/
      margin-top: 24px;
      background-color: #ebeff4;
      /*border-radius: 15px;*/
      -webkit-appearance: none;
      height: 4px;
      padding: 0;
      border: none;
      outline: none;
      /*input的长度为80%,margin-left的长度为10%*/
    }
    .volume-input::-webkit-slider-thumb {
      -webkit-appearance: none; /*去除默认样式*/
      cursor: pointer;
      top: 0;
      height: 20px;
       20px;
      transform: translateY(0px);
      background: #fff;
      border-radius: 15px;
      border: 5px solid #6190e8;
      /*-webkit-box-shadow: 0 -1px 1px #fc7701 inset;*/
    }
    video:-webkit-full-screen {
      z-index: 9 !important;
       100% !important;
      height: 100% !important;
    }
    video::-webkit-media-controls {
      display: none !important;
    }
    .video-progress {
      position: absolute;
       100%;
      left: 0;
      bottom: 0;
      height: 4px;
      z-index: 999999;
    }
    .video-progress-current {
      position: absolute;
       0%;
      left: 0;
      bottom: 0;
      height: 4px;
      border-radius: 2px;
      background: tomato;
    }
    </style>


  • 相关阅读:
    函数二 10
    函数初识 09
    文件操作 08
    数据类型的补充 day07
    小数据池 深浅copy 集合
    python Mysql 多条件查询
    ElasticSearch Python 基本操作
    用PyInstaller把Python代码打包成单个独立的exe可执行文件
    python 编译EXE文件
    Git 创建新分支检查分支
  • 原文地址:https://www.cnblogs.com/zzh965390267/p/13176641.html
Copyright © 2020-2023  润新知