vue 自定义audio标签

作者: 冷r | 来源:发表于2020-09-30 08:39 被阅读0次

    改变audio标签样式

    1. 改变原生audio样式
    2. 隐藏audio标签,用div实现一个样式

    代码详细https://github.com/sjq4499/vue-audio

    第一种 改变原生audio标签

    注:1.在个别浏览器样式会不生效,尤其是在iPhone上
    2. 按钮颜色只能是黑色和白色

    <template>
      <audio controls controlslist="nodownload">
        <source :src="fileurl" type="audio/mp3" />您的浏览器不支持 HTML5 audio 标签。
      </audio>
    </template>
    
    <script>
    
    export default {
      props: ['fileurl']
    
    }
    </script>
    
    <style lang="scss" scoped>
    audio {
      width: 100%;
      height: 40px;
      outline: none;
      filter: invert(180); //c3 filter(滤镜) 属性
    }
    
    audio::-webkit-media-controls-enclosure {
      background: rgb(129, 73, 200);
      /* 滤镜反转为 rgba(0, 162, 255, 1);rgba(255, 93, 0, 0.8)  #7eb637   10,10,10  #757575 */
      border-radius: 4px;
    }
    .media-controls-container,
    .media-controls-container * {
      background: rgb(129, 73, 200);
      //滤镜反转为 rgba(0, 162, 255, 1);rgba(255, 93, 0, 0.8)  #7eb637
      border-radius: 4px;
    }
    audio::-webkit-media-controls-play-button {
      height: 22px;
      width: 22px;
      min-width: 22px;
      border-radius: 50%;
      flex-basis: 22px;
    }
    
    // 音量隐藏
    audio::-webkit-media-controls-volume-control-container {
      display: none;
    }
    
    audio::-webkit-media-controls-current-time-display {
      order: 1; //设置弹性盒对象元素的顺序
      color: #000;
      text-shadow: unset;
    }
    
    audio::-webkit-media-controls-time-remaining-display {
      order: 2;
      color: rgba(0, 0, 0, 0.6);
      text-shadow: unset;
    }
    </style>
    
    第二种适用于pc

    注:播放按钮需要引icon 进度条是鼠标事件在h5不生效

    
    <template>
      <div>
        <audio @timeupdate="updateProgress" controls ref="audioRef" style="display: none">
          <source :src="fileurl" type="audio/mpeg" />您的浏览器不支持音频播放
        </audio>
        <div class="audio-right">
          <span
            :class="audioStatus!=='stop'?'icon-zanting':' icon-weibiaoti518'"
            @click="playAudio"
            class="dialogAudioPlay iconfont"
          ></span>
          <div class="progress-bar-bg" id="progressBarBg">
            <span id="progressDot" v-dragto></span>
            <div class="progress-bar" id="progressBar"></div>
          </div>
          <div class="audio-time" style="min-height: 10px">
            <span class="audio-length-current" id="audioCurTime">{{audioStart}}</span>/
            <span class="audio-length-total">{{transTime(duration)}}</span>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: ['fileurl', 'duration'],
      data () {
        return {
          audioStatus: '',
          audioStart: '0:00',
        }
      },
    
      directives: {
        dragto: {
          bind: function (el, drag, vnode) {
            let odiv = el;   //获取当前元素
            odiv.onmousedown = (e) => {
              let disX = e.clientX - odiv.offsetLeft
              let wdiv = document.getElementById('progressBarBg').clientWidth
              let audio = vnode.context.$refs.audioRef
              if (!audio.paused || audio.currentTime != 0) { // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
                document.onmousemove = (e) => {
                  let chaxs = e.clientX - disX
                  let ratemin = chaxs / wdiv
                  let rate = ratemin * 100
                  if (rate >= 0 && rate <= 100) {
                    document.getElementById('progressBar').style.width = rate + '%'
                    odiv.style.left = rate + '%'
                    audio.currentTime = audio.duration * ratemin;
                  }
                }
                document.onmouseup = (e) => {
                  document.onmousemove = null;
                  document.onmouseup = null;
                }
              }
            }
          }
        }
      },
      methods: {
        //播放暂停控制
        playAudio () {
          let recordAudio = this.$refs.audioRef; //获取audio元素
          if (recordAudio.paused) {
            //   this.audioImg = "./dialogDetailPause.png"
            recordAudio.play();
          } else {
            //   this.audioImg = "./dialogDetailPlay.png"
            recordAudio.pause();
          }
        },
        //更新进度条与当前播放时间
        updateProgress (e) {
          var value = e.target.currentTime / e.target.duration
          if (document.getElementById('progressBar')) {
            document.getElementById('progressBar').style.width = value * 100 + '%'
            document.getElementById('progressDot').style.left = value * 100 + '%'
            if (e.target.currentTime == e.target.duration) {
              this.audioStatus = 'zanting'
            }
          } else {
            this.audioStatus = 'zanting'
          }
    
          this.audioStart = this.transTime(this.$refs.audioRef.currentTime)
        },
        /**
         * 音频播放时间换算
         * @param {number} value - 音频当前播放时间,单位秒
         */
        transTime (value) {
          var time = "";
          var h = parseInt(value / 3600);
          value %= 3600;
          var m = parseInt(value / 60);
          var s = parseInt(value % 60);
          time = h + ":" + m + ":" + s;
          return time;
        },
      }
    
    
    }
    </script>
    
    <style lang="scss"  scoped>
    .audio-right {
      width: 100%;
      height: 49px;
      line-height: 49px;
      background: #7eb637;
      border-radius: 6px;
      display: flex;
      padding: 0 15px;
      .dialogAudioPlay {
        cursor: pointer;
        color: #fff;
        font-size: 20px;
      }
      .progress-bar-bg {
        background-color: #fff;
        flex: 1;
        position: relative;
        height: 2px;
        top: 50%;
        margin-top: -1px;
        cursor: pointer;
        margin: 0 10px;
        span {
          content: ' ';
          width: 10px;
          height: 10px;
          border-radius: 50%;
          -moz-border-radius: 50%;
          -webkit-border-radius: 50%;
          background-color: #fff;
          position: absolute;
          left: 0%;
          top: 50%;
          margin-top: -5px;
          margin-left: -5px;
          cursor: pointer;
        }
      }
      .progress-bar {
        background-color: #fff;
        width: 0%;
        height: 2px;
      }
    
      .audio-time {
        overflow: hidden;
        color: #fff;
        font-size: 14px;
        .audio-length-total {
          float: right;
        }
        .audio-length-current {
          float: left;
        }
      }
    }
    </style>
    
    第三种适用于H5

    注 :进度条是vant 播放按钮是icon

    
    <template>
      <div class="myaudio">
        <audio @timeupdate="updateProgress" controls ref="audioRef" style="display: none">
          <source :src="fileurl" type="audio/mpeg" />您的浏览器不支持音频播放
        </audio>
        <div class="audio-right">
          <span
            :class="audioStatus!=='stop'?'icon-zanting':' icon-weibiaoti518'"
            @click="playAudio"
            class="dialogAudioPlay iconfont"
          ></span>
          <div class="progress-bar-bg">
            <van-slider @change="onChange" button-size="15px" v-model="value" />
          </div>
          <div class="audio-time" style="min-height: 10px">
            <span class="audio-length-current" id="audioCurTime">{{videoStart}}</span>/
            <span class="audio-length-total">{{transTime(duration)}}</span>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: ["fileurl", 'duration'],
      data: function () {
        return {
          audioStatus: 'stop',
          videoStart: '00:00',
          value: 0
        };
      },
      methods: {
        //播放暂停控制
        playAudio (e) {
          let recordAudio = this.$refs.audioRef; //获取audio元素
          if (recordAudio.paused) {
            recordAudio.play();
            this.audioStatus = "run"
          } else {
            recordAudio.pause();
            this.audioStatus = "stop"
          }
        },
        //更新进度条与当前播放时间
        updateProgress (e) {
          var value = e.target.currentTime / this.duration
          this.value = value * 100
          if (e.target.currentTime > this.duration) {
            this.audioStatus = 'stop'
            this.value = 0
            this.videoStart = this.transTime(0)
            return
          }
          this.value = value * 100
          this.videoStart = this.transTime(this.$refs.audioRef.currentTime)
        },
        /**
         * 音频播放时间换算
         * @param {number} value - 音频当前播放时间,单位秒
         */
        transTime (value) {
          var time = "";
          var h = parseInt(value / 3600);
          value %= 3600;
          var m = parseInt(value / 60);
          m = m < 10 ? '0' + m : m
          var s = parseInt(value % 60);
          s = s < 10 ? '0' + s : s
          time = m + ":" + s;
          return time;
        },
        // 进度条
        onChange (val) {
          let recordAudio = this.$refs.audioRef; //获取audio元素
          if (!recordAudio.paused || recordAudio.currentTime != 0) {
            recordAudio.currentTime = recordAudio.duration * val / 100
            this.videoStart = this.transTime(val / 100 * this.duration)
          }
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .audio-right {
      width: 100%;
      margin-top: 10px;
      height: 49px;
      line-height: 49px;
      background: #7eb637;
      border-radius: 6px;
      display: flex;
      padding: 0 15px;
      .dialogAudioPlay {
        cursor: pointer;
        color: #fff;
        font-size: 20px;
      }
      .progress-bar-bg {
        background-color: #fff;
        flex: 1;
        position: relative;
        height: 2px;
        top: 50%;
        margin-top: -1px;
        cursor: pointer;
        margin: 0 10px;
        span {
          content: ' ';
          width: 10px;
          height: 10px;
          border-radius: 50%;
          -moz-border-radius: 50%;
          -webkit-border-radius: 50%;
          background-color: #fff;
          position: absolute;
          left: 0%;
          top: 50%;
          margin-top: -5px;
          margin-left: -5px;
          cursor: pointer;
        }
        .van-slider__bar {
          background-color: #a4e354;
        }
      }
      .progress-bar {
        background-color: #fff;
        width: 0%;
        height: 2px;
      }
    
      .audio-time {
        overflow: hidden;
        color: #fff;
        font-size: 14px;
        span {
          color: #fff;
        }
        .audio-length-total {
          float: right;
        }
        .audio-length-current {
          float: left;
        }
      }
    }
    </style>
    
    效果

    扩展:video可以适用poster设置第一帧图 七牛云上传的视频加?vframe/jpg/offset/0自动获取

    相关文章

      网友评论

        本文标题:vue 自定义audio标签

        本文链接:https://www.haomeiwen.com/subject/uqnfuktx.html