baozhengrui

导航

音频播放

<template>
  <div class="audio-play">
    <audio
        ref="audio"
        preload
        @pause="handlePause"
        @play="handleTimeProgress"
        @canplay="computedFullTime"
        :src="audioUrl"
    ></audio>
    <div class="control-btn" @click="playStatusChange">
      <div :class="playStatus ? 'play' : 'stop'"></div>
    </div>
    <div class="control-line">
      <div ref="fullLine" class="bottom-line">
        <div class="played-line" :style="scaleProgress"></div>
        <div ref="point" class="play-point" @mousedown="handleMouseDown">
          <div class="point"></div>
        </div>
<!--        <div class="played-time">{{ playTime }}</div>-->
      </div>
<!--      <div class="al-time">{{ fullTime }}</div>-->
    </div>
  </div>
</template>

<script>
export default {
  name: "audio-play",
  props:{
    audioUrl:{
      type:String,
      default:''
    },
    playStatus:{
      type:Boolean,
      default:false
    }
  },
  data(){
    return{
      playTime:'',
      fullTime:'',
      scale:0,
    }
  },
  computed: {
    scaleProgress() {
      if (this.scale) {
        return 'width:' + this.scale * 100 + '%';
      } else {
        return 'width:0';
      }
    }
  },
  methods:{
    //播放按钮点击切换事件
    playStatusChange() {
      this.playStatus = !this.playStatus;
      if (this.playStatus) {
        this.$refs.audio.play();
      } else {
        this.$refs.audio.pause();
      }
    },
    handleTimeProgress() {
      this.timer = setInterval(this.playing, 1000);
    },
    playing() {
      // 正在播放中
      this.scale = this.$refs.audio.currentTime / this.$refs.audio.duration;
      this.playTime = this.formatTime(this.$refs.audio.currentTime);
    },
    handlePause() {
      this.playStatus = false;
      clearInterval(this.timer);
    },
    computedFullTime() {
      this.fullTime = this.formatTime(this.$refs.audio.duration);
    },
    formatTime(val) {
      val = Math.round(val);
      const min = Math.floor(val / 60);
      const sec = val % 60;
      return this.setZero(min) + ':' + this.setZero(sec);
    },
    setZero(val) {
      if (val < 10) {
        return '0' + val;
      } else {
        return '' + val;
      }
    },
    //鼠标按下事件触发
    handleMouseDown(ev) {
      const that = this;
      const downX = ev.pageX;
      const downL = this.$refs.point.offsetLeft;
      //鼠标移动事件
      document.onmousemove = ev => {
        let scale =
            (ev.pageX - downX + downL + 8) / that.$refs.fullLine.offsetWidth;
        if (scale < 0) {
          scale = 0;
        } else if (scale > 1) {
          scale = 1;
        }
        that.scale = scale;
        that.$refs.audio.currentTime = scale * that.$refs.audio.duration;
        that.playTime = that.formatTime(that.$refs.audio.currentTime);
      };
      document.onmouseup = () => {
        document.onmousemove = document.onmouseup = null;
      };
      ev.preventDefault();
    }
  }
}
</script>

<style scoped lang="scss">
.audio-play {
  height: 18px;
  width: 95%;
  margin-left: 8px;
  display: flex;
  position: relative;
  top: -12px;
.control-btn {
  height: 18px;
  width: 18px;
  cursor: pointer;
.play {
  height: 18px;
  width: 18px;
  background: url('@/assets/image/stop.png');
  background-size: 100% 100%;
}
.stop {
  height: 18px;
  width: 18px;
  background: url('@/assets/image/play.png');
  background-size: 100% 100%;
}
}
.control-line {
  width: 80%;
  margin-left: 6px;
.al-time {
  float: right;
  opacity: 0.6;
  font-family: PingFangSC-Semibold;
  font-size: 12px;
  color: #64e59e;
  margin-top: 4px;
}
.bottom-line {
  display: flex;
  position: relative;
  margin-top: 8px;
  height: 4px;
  background: rgba(44,116,79,0.25);
  border-radius: 2px;
.played-line {
  background: linear-gradient(90deg,rgba(149,255,225,0.75), rgba(100,229,158,0.95));
  border-radius: 2px;
  height: 4px;
// width: 20%;
}
.played-time {
  position: absolute;
  opacity: 0.6;
  font-family: PingFangSC-Semibold;
  font-size: 12px;
  color: #64e59e;
  left: -18px;
  top: 10px;
}
.play-point {
  position: relative;
  height: 10px;
  width: 10px;
  background: #ffffff;
  border: 1px solid #64e59e;
  border-radius: 5px;
  margin-left: -5px;
  margin-top: -4px;
.point {
  background: #64e59e;
  height: 4px;
  width: 4px;
  margin: 3px;
  border-radius: 2px;
}
}
}
}
}
</style>


posted on 2024-08-12 17:11  芮艺  阅读(132)  评论(0)    收藏  举报