种地 发表于 2024-6-21 13:20:28

简单利用vue2和elementUI自界说audio支持拖拽进度

<template>
<div class="music-player">
    <audio ref="audio" :src="src" @timeupdate="updateTime" @loadedmetadata="loadedmetadata" @ended="onAudioEnded"></audio>
    <!-- 播放暂停按钮 -->
    <div class="cm-btn-left" @click="togglePlay">
      <img src="../../../../public/img/icon/play.png" v-show="!isPlaying">
      <img src="../../../../public/img/icon/pause.png" v-show="isPlaying">
    </div>
    <!-- 时间 -->
    <div class="cm-time">
      <span>{{ currentTimeShow }}</span> / <span>{{ durationShow }}</span>
    </div>
    <!-- 播放进度条 -->
    <div class="cm-progress" @mousedown="handleMouseDown">
      <el-slider v-model="progress" :max="duration" :format-tooltip="formatTime" @change="progressChange"></el-slider>
    </div>
    <!-- 倍速控制 -->
    <div class="playback-rate-wrapper">
      <el-select v-model="playbackRate" @change="changePlaybackRate">
      <el-option
          v-for="item in speed"
          :key="item.value"
          :label="item.label"
          :value="item.value">
      </el-option>
      </el-select>
    </div>
    <!-- 音量控制 -->
    <div class="volumn-wrapper">
   <el-popover
      popper-class="volumn-popover"
      placement="right"
      width="30px"
      trigger="click">
      <el-slider
          v-model="volumnValue"
          vertical
          tooltip-class="volumn-tooltip"
          height="80px"
          @change="volumnChange">
      </el-slider>
      <el-button slot="reference" type="text"><img src="../../../../public/img/icon/volumn.png"></el-button>
      </el-popover>
    </div>
</div>
</template>

<script>

export default {
props: {
    src: String,
},
data() {
    return {
      isPlaying: false,
      currentTime: 0,
      progress: 0,
      duration: 0,
      playbackRate: 1,
      speed: [
      {
          label: '0.5x',
          value: 0.5
      },
      {
          label: '0.75x',
          value: 0.75
      },
      {
          label: '1x',
          value: 1
      },
      {
          label: '1.5x',
          value: 1.5
      },
      {
          label: '2x',
          value: 2
      }
      ],
      volumnValue: 50,
      lastTimeUpdate: null
    };
},
computed: {
    currentTimeShow: function () {
      return this.formatTime(this.currentTime);
    },
    durationShow: function () {
      return this.formatTime(this.duration);
    }
},
mounted() {

},
beforeDestroy() {
   
},
methods: {
    // 外部点击暂停播放
    resetAudio() {
      this.$refs.audio.pause();
      this.isPlaying = false;
      this.playbackRate = 1;
      this.volumnValue = 50;
      this.duration = 0;
      setTimeout(() => {
      this.currentTime = 0;
      }, 50);
    },
    // 播放暂停按钮点击事件
    togglePlay() {
      if (!this.src || this.src.length === 0) {
      return
      }
      if (this.isPlaying) {
      this.$refs.audio.pause();
      this.isPlaying = false;
      } else {
      this.$refs.audio.play();
      this.$refs.audio.volume = this.volumnValue / 100;
      this.isPlaying = true;
      }
    },
    // 格式化播放时间
    formatTime(seconds) {
      const minutes = Math.floor(seconds / 60);
      const secondsRemainder = Math.round(seconds % 60);
      return `${minutes}:${secondsRemainder < 10 ? '0' : ''}${secondsRemainder}`;
    },
    // 倍速控制
    changePlaybackRate() {
      this.$refs.audio.playbackRate = this.playbackRate;
    },
    // 更新播放时间
    updateTime() {
      this.currentTime = this.$refs.audio.currentTime;
      this.progress = this.currentTime;
    },
    // 获取播放总时长
    loadedmetadata() {
      this.duration = this.$refs.audio.duration;
    },
    // 播放结束
    onAudioEnded() {
      this.isPlaying = false;
    },
    // 进度条鼠标按下事件
    handleMouseDown() {
      this.$refs.audio.pause();
    },
    // 设置进度
    progressChange(e) {
      this.$refs.audio.currentTime = e;
      this.progress = e;
      this.$refs.audio.play();
      this.isPlaying = true;
    },
    // 设置音量
    volumnChange(e) {
      this.$refs.audio.volume = e / 100;
    },
},
};
</script>

<style lang="scss" scoped>
.music-player {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0px 20px;
    background-color: #f5f5f5;
    border-radius: 27px;
    height: 54px;
    width: 100%;

    .cm-btn-left {
      cursor: pointer;
      width: 22px;
      height: 22px;
      img {
      width: 22px;
      height: 22px;
      }
    }

    .volumn-wrapper {
      img {
      width: 20px;
      height: 18px;
      }
    }

    .cm-time {
      font-size: 14px;
      color: #404040;
      margin: 0 10px;
    }

    .cm-progress {
      flex: 1;
      margin: 0 15px 0 10px;

      ::v-deep .el-slider__button {
      border-color: #404040 !important;
      }

      ::v-deep .el-slider__bar {
      background-color: #404040 !important;
      }
    }

    .playback-rate-wrapper {
      margin-right: 10px;
      ::v-deep .el-input__suffix {
      display: none;
      }

      ::v-deep .el-input__inner {
      height: 28px;
      width: 45px;
      text-align: center;
      padding: 0px !important;
      font-size: 12px;
      }
    }
}

::v-deep .el-slider__button {
    width: 12px;
    height: 12px;
}

::v-deep .el-popover {
    min-width: auto !important;
}
</style> app.vue中或者其他全局变量中修改下样式
.volumn-popover {
  min-width: auto !important;
}
.volumn-tooltip {
  z-index: 99999 !important;
}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 简单利用vue2和elementUI自界说audio支持拖拽进度