vue3 自定义音频

0 阅读1分钟

因为项目的需求,要在页面上加载动态的音乐播放器,所以需要封装audio组件进行引入。

  1. 隐藏原生的audio
  2. 通过自定义的dom实现自定义样式
  3. 控制dom操作audio 对象的属性和方法

组件:

<template>  <div>    <audio @timeupdate="updateProgress" controls ref="audioRef">      <source :src="fileurl" />      您的浏览器不支持音频播放    </audio>    <div class="audio-right">      <div class="play-stop-icon" @click="playAudio">        <CaretRightOutlined          v-if="audioStatus !== 'pause'"          class="dialogAudioPlay"        ></CaretRightOutlined>        <PauseOutlined v-else class="dialogAudioPlay"></PauseOutlined>      </div>      <div class="progress-bar-bg" id="progressBarBg">        <Slider :tip-formatter="formatter" v-model:value="playTime" @change="sliderChange" />      </div>      <div class="audio-time" style="min-height: 10px">        <span class="audio-length-current" id="audioCurTime">{{ audioStart }}</span        >/        <span class="audio-length-total">{{ duration }}</span>      </div>    </div>  </div></template><script lang="ts">  import {    defineComponent,    ref,    reactive,    watchEffect,    inject,    onMounted,    nextTick,    watch,    computed,    toRef,    toRefs,  } from 'vue';  import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue';  import { Slider } from 'ant-design-vue';  export default defineComponent({    components: {      CaretRightOutlined,      PauseOutlined,      Slider,    },    props: {      fileurl: "",      duration: "",//音频时长    },    setup(props, context) {      let audioStatus = ref('play');      let audioStart = ref<number | string>('0:00');      let audioVolume = ref(0.5);      let audioHuds = ref(false);      let audioRef = ref<HTMLAudioElement | null>(null);      let durationSecond = ref<number>();      let playPercentage = ref<number>();      let playTime = ref<number | string>('0:00');      function fetch() {        let myVid = audioRef.value;        if (!myVid) return;        myVid.loop = false;        // 监听音频播放完毕        myVid.addEventListener(          'ended',          function () {            audioStatus.value = 'play'; // 显示播放icon          },          false,        );        if (myVid != null) {          myVid.oncanplay = function () {            durationSecond.value = myVid?.duration;          };          myVid.volume = 0.5; // 设置音量50%        }      }      // 播放暂停控制      function playAudio() {        let recordAudio = audioRef.value; // 获取audio元素        if (recordAudio?.paused) {          recordAudio?.play();          audioStatus.value = 'pause';        } else {          recordAudio?.pause();          audioStatus.value = 'play';        }      }      const formatter = (value: number) => {        playTime.value = value;        return audioStart.value;      };      // 更新进度条与当前播放时间      function updateProgress(e) {        playPercentage.value = e.target.currentTime / e.target.duration;      }      function sliderChange() {          audioRef.value.currentTime = (Number(playTime.value) * durationSecond.value) / 100;          audioRef.value.play();      }      onMounted(() => {        fetch();      });      return {        audioStatus,        audioStart,        audioVolume,        audioHuds,        audioRef,        fetch,        playAudio,        updateProgress,        playTime,        formatter,        playPercentage,        durationSecond,        sliderChange,      };    },  });</script><style lang="scss" scoped>  </style>

具体样式就根据各自需求进行处理,主要控制部分逻辑还是在拖拽快进上面