howler.js中文网址:http://www.npmdoc.org/howlerzhongwenwendanghowler-jszhongwenjiaochengjiexi.html

howler.js官网:

https://howlerjs.com/ 

 本例子使用技术如下:

Vue3++howler

实现音频播放对话框

 howler安装:npm i howler

 实现效果如下:

 代码如下:

<template>
    <a-modal v-model:visible="visible"  :footer="null" destroyOnClose closable>
      <div class="audio-top">
        <span class="audio-top-time">{{startTime}}</span>
        <a-slider  v-model:value="value" :tip-formatter="formatter"
        @change="timeChange" />
         <span class="audio-top-time">{{endTime}}</span>
      </div>
     <div class="audio-buttom">
      <div class="audio-buttom-btn">
        <a-button type="primary" shape="circle" @click="backUp">
          <template #icon> <FastBackwardFilled :style="{fontSize:'20px'}"/></template>
        </a-button>
        <a-button v-if="!playing" type="primary" shape="circle" @click="play">
          <template #icon> <CaretRightOutlined  :style="{fontSize:'20px'}"/></template>
        </a-button>
        <a-button v-if="playing" type="primary" shape="circle" @click="pause">
          <template #icon> <PauseOutlined   :style="{fontSize:'20px'}"/></template>
        </a-button>
        <a-button type="primary" shape="circle" @click="advance">
          <template #icon> <FastForwardFilled :style="{fontSize:'20px'}"/></template>
        </a-button>
      </div>
      <a-slider  v-model:value="volume" @change="volumeChange"/>
     </div>
    </a-modal>
</template>

<script>
import { Modal, Slider } from 'ant-design-vue';
import {
  reactive, toRefs, watch, ref,
} from 'vue';
import {
  FastBackwardFilled, CaretRightOutlined, FastForwardFilled, PauseOutlined,
} from '@ant-design/icons-vue';
import { Howl } from 'howler';

export default {
  components: {
    FastBackwardFilled,
    CaretRightOutlined,
    FastForwardFilled,
    PauseOutlined,
    [Modal.name]: Modal,
    [Slider.name]: Slider,
  },
  setup() {
    const state = reactive({
      visible: false,
      loading: false,
      volume: 50,
      loudness: 0.5, // 音量
      audioSrc: [ // 播放列表
      ],
      value: 0, // 播放进度条
      playing: false, // 播放状态 false停止  true播放
      startTime: '00.00', // 开始时间
      endTime: '00.00', // 结束时间
    });
    const sound = ref();
    // 分秒转化
    const formatTime = (secs) => {
      const minutes = Math.floor(secs / 60) || 0;
      const seconds = Math.floor(secs - minutes * 60) || 0;
      return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    };
    // 计算出 当前进度条时间 以及进度条位置
    const setTimerAndValue = () => {
      const seek = sound.value.seek();
      if (typeof seek === 'number') {
        const startTimer = formatTime(Math.round(seek));
        // eslint-disable-next-line no-underscore-dangle
        const endTimer = formatTime(Math.round(sound.value._duration));
        // eslint-disable-next-line no-underscore-dangle
        state.value = Math.round((seek / sound.value._duration) * 100) || 0;
        state.startTime = startTimer;
        state.endTime = endTimer;
      }
    };
    const step = () => {
      setTimerAndValue();
      requestAnimationFrame(step);
    };
    // 监听 对话框打开
    watch(() => state.visible, (newValue) => {
      if (newValue === true) {
        state.playing = true;
        sound.value.play();// 播放
      } else {
        state.playing = false;
        sound.value.stop();// 结束
      }
    });
    // 抽屉开启
    const showModal = (e) => {
      state.loading = true;
      state.volume = 50;
      state.loudness = 0.5;
      state.audioSrc = e.audioSrc;
      sound.value = new Howl({
        src: state.audioSrc,
        volume: state.loudness,
        autoplay: true,
        loop: true,
        html5: true,
        preload: true,
        onplay: onplay = () => {
          step();
        },
      });
      state.visible = true;
    };
    // 播放
    const play = () => { state.playing = true; sound.value.play(); };
    // 暂停
    const pause = () => { state.playing = false; sound.value.pause(); step(); };
    // 前进
    // eslint-disable-next-line no-underscore-dangle
    const advance = () => { sound.value.seek(sound.value._duration * (state.value / 100) + 5); };
    // 后退
    // eslint-disable-next-line no-underscore-dangle
    const backUp = () => { sound.value.seek(sound.value._duration * (state.value / 100) - 5); };
    // 音量设置
    const volumeChange = (e) => { sound.value.volume(e * 0.01); };
    // 时间进度条变化事件
    // eslint-disable-next-line no-underscore-dangle
    const timeChange = (e) => { sound.value.seek((sound.value._duration * e) / 100); };
    // 时间进度条提示
    // eslint-disable-next-line no-underscore-dangle
    const formatter = (value) => formatTime((value / 100) * sound.value._duration);
    return {
      ...toRefs(state),
      sound,
      showModal,
      formatter,
      formatTime,
      play,
      pause,
      advance,
      backUp,
      volumeChange,
      setTimerAndValue,
      timeChange,
    };
  },
};
</script>

<style lang="less" scoped>
.audio-buttom{
  display: flex;
  justify-content: space-between;
  align-items: center;
  :deep(.ant-slider){
    width: 300px;
  }
  &-btn{
    width: 120px;
    display: flex;
    justify-content: space-around;
  }
}
.audio-top{
  display: flex;
  justify-content: space-around;
  align-items: center;
  &-time{
    width: 40px;
  }
  :deep(.ant-slider){
    width: 100%;
  }
}
</style>

Logo

前往低代码交流专区

更多推荐