vue中自定义audio组件,支持渲染多个audio

在这里插入图片描述

const albumItemList = [
  {
    voice_url: '',
    duration: "00:59",
    start_duration: "00:00",
    progress: 0,
    stop_s: 0,
  },
  {
    voice_url: '',
    duration: "01:59",
    start_duration: "00:00",
    progress: 0,
    stop_s: 0,
  }
]

html

  <div class="directory-list">
        <div
            class="directory-list-item"
            v-for="(item, index) in albumItemList"
            :key="index"
          >
            <div class="progress">
              <div class="start-time">{{ item.start_duration }}</div>
              <el-slider
                v-model="item.progress"
                :show-tooltip="false"
                @change="handleChangeSlider($event, item)"
              ></el-slider>
              <div class="end-time">{{ item.duration }}</div>
            </div>
            <img
              v-show="item.item_id !== albumItem.item_id"
              src="@/assets/images/bofang.png" //播放的图片
              alt=""
              @click="handlePlay(item)"
            />
            <img
              v-show="item.item_id === albumItem.item_id"
              src="@/assets/images/bofang-2.png" //暂停的图片
              alt=""
              @click="handleStop"
            />
          </div>
        </div>
        
    <audio
      v-show="false"
      ref="audioPlayer"
      :src="albumItem.voice_url"
      controls
      @timeupdate="onTimeUpdate"
    ></audio>

js

export default {
  data() {
    return {
      isStop: false,
      albumItem: {},
      albumItemList: [],
    };
  },
  methods: {
      toTime(sec) {
      let s = sec % 60 < 10 ? "0" + (sec % 60) : sec % 60;
      let min =
        Math.floor(sec / 60) < 10
          ? "0" + Math.floor(sec / 60)
          : Math.floor(sec / 60);
      return min + ":" + s;
    },
    timeToSeconds(timeString) {
      const [minutes, seconds] = timeString.split(":").map(Number);
      return minutes * 60 + seconds;
    },
      handlePlay(item) {
      this.albumItem = item;
      const e = item.stop_s;
      const duration = parseInt(this.timeToSeconds(item.duration));
      const progress = (e / duration) * 100;
      this.albumItemList.forEach((item) => {
        if (item.item_id === this.albumItem.item_id) {
          item.progress = progress;
        }
      });
      this.$nextTick(() => {
        if (item.stop_s !== 0) this.$refs.audioPlayer.currentTime = e;
        this.$refs.audioPlayer.play();
      });
    },
        handleStop() {
      this.albumItem = {};
      this.$nextTick(() => {
        this.$refs.audioPlayer.pause();
      });
    },
     handleReset() {
      this.albumItemList.forEach((item) => {
        if (item.item_id === this.albumItem.item_id) {
          item.start_duration = "00:00";
          item.progress = 0;
          item.stop_s = 0;
          this.albumItem = {};
        }
      });
    },
        handleChangeSlider(e, item) {
      this.albumItem = item;
      this.$nextTick(() => {
        this.$refs.audioPlayer.pause();
      });
      this.isStop = true;
      const ct = (e * this.timeToSeconds(item.duration)) / 100;
      this.$nextTick(() => {
        this.$refs.audioPlayer.currentTime = ct;
        this.$refs.audioPlayer.play();
      });
      this.isStop = false;
    },
      onTimeUpdate() {
      if (this.isStop) return;
      const duration = parseInt(this.$refs.audioPlayer.duration);
      const curr = parseInt(this.$refs.audioPlayer.currentTime);
      const progress = (curr / duration) * 100;
      this.albumItemList.forEach((item) => {
        if (item.item_id === this.albumItem.item_id) {
          item.progress = progress;
          item.stop_s = curr;
          item.start_duration = this.toTime(curr);
        }
      });
      if (progress === 100) this.handleReset();
    },
  }
}

时间紧,有些逻辑可以拆出来写一个公共函数,大佬们可以自行优化一下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值