Vue.js前端开发那些事儿大前端

vue 自定义audio标签

2020-09-30  本文已影响0人  冷r

改变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自动获取

上一篇 下一篇

猜你喜欢

热点阅读