当前位置:首页 » 《资源分享》 » 正文

VUE3开箱即用的音频播放组件(基于原生audio)

10 人参与  2024年11月25日 16:01  分类 : 《资源分享》  评论

点击全文阅读


1 效果展示

2 组件文件

AudioBase.vue

注:我是使用unocss语法来编写css 如果项目没有搭载unocss 将其相应的转换为css即可

<template>  <div    :style="{      height: `${100 + (textDiv ? textDiv.clientHeight + 10 : 0)}px`,    }"    p-10    bg-white    w-500    rounded-xl    border="1px solid gray-200 "  >    <div>      <div inline-flex text-size-6xl>        与        <div mx-5 inline-flex>{{ $props.customerName }}</div>        进行通话      </div>      <div text-gray-500 inline-flex float-right>{{ $props.callTime }}</div>    </div>    <div class="bg-[--td-brand-color-1]" float-left flex-center pl-9 pr-11 rounded-55 w-330 h-40 mt-10>      <span w-50 inline-block mr-8> {{ transTime(audioCurrent) }} </span>      <div class="progress" w-120 mx-10 my-0>        <t-slider          v-model="playProgress"          :tooltip-props="{            theme: 'light',            content: transTime((changeVal * audioDuration) / 100),          }"          @change="change"          @change-end="changeEnd"        />      </div>      <span w-50 inline-block mr-6>{{ transTime(audioDuration) }}</span>      <t-icon        v-if="!playStatus"        name="play-circle"        class="color-[--td-brand-color-6]"        w-34        h-34        ml-7        cursor-pointer        @click="onPlay"      ></t-icon>      <t-icon        v-else        class="color-[--td-brand-color-6]"        w-34        h-34        ml-7        cursor-pointer        name="pause-circle"        @click="onPause"      ></t-icon>    </div>    <audio ref="audioRef" :src="url" @canplay="onCanplay" />    <div ml-20 flex-center mt-10>      <t-popup v-model:visible="speedVisible" placement="top" :width="50">        <template #content>          <div            v-for="item in speedList"            :key="item.value"            mb-17            cursor-pointer            text-center            @click="onChangeSpeed(item.value)"          >            <span>{{ item.label }}</span>          </div>        </template>        <div inline ml-5 cursor-pointer>          <span class="text-[var(--td-brand-color-6)]" cursor-pointer @click="onHandleSpeed"            >{{ activeSpeed.toFixed(1) }}x</span          >          <div color-gray-6 text-12>倍速</div>        </div>      </t-popup>      <div inline ml-20 flex-col-center cursor-pointer>        <t-icon class="color-[var(--td-brand-color-6)]" ml-4 w-20 h-18 name="cloud-download"></t-icon>        <div color-gray-6 text-12>下载</div>      </div>      <div inline ml-20 flex-col-center cursor-pointer @click="handleText">        <t-icon class="color-[var(--td-brand-color-6)]" ml-5 w-20 h-18 name="translate"></t-icon>        <div color-gray-6 text-12>转文字</div>      </div>    </div>    <div      v-if="showText"      ref="textDiv"      class="bg-[var(--td-brand-color-1)]"      p-10      rounded-5      mt-10      max-h-190      overflow-auto      overflow-y-auto    >      {{ $props.text }}    </div>  </div></template><script lang="ts" setup>import moment from 'moment';import { defineProps, onMounted, ref } from 'vue';defineProps({  customerName: {    type: String,    default: 'xxx',// 名字  },  callTime: {    type: String,    default: '2024-08-02 16:20:35',  },  url: {    type: String,    default: 'http://music.163.com/song/media/outer/url?id=1337065812.mp3',  },  text: {    type: String,    default: '默认的内容还可以吧我是默认的语音转文字内容看看长度如何呢默认的内容还可以吧我是默认的语音转文字',  },});const speedList = [  {    label: '2x',    value: 2,  },  {    label: '1.5x',    value: 1.5,  },  {    label: '1x',    value: 1,  },  {    label: '0.75x',    value: 0.75,  },];onMounted(() => {  clearInterval(timeInterval.value);});const speedVisible = ref<boolean>(false); // 设置音频播放速度弹窗const audioRef = ref(); // 音频标签对象const activeSpeed = ref(1); // 音频播放速度const audioDuration = ref(0); // 音频总时长const audioCurrent = ref(0); // 音频当前播放时间const playStatus = ref<boolean>(false); // 音频播放状态:true 播放,false 暂停const playProgress = ref(0); // 音频播放进度const timeInterval = ref(); // 获取音频播放进度定时器const showText = ref(false);const textDiv = ref();const changeVal = ref(0);/** FUNCTION */// 拖动进度条const change = (val) => {  changeVal.value = val;};const changeEnd = (val: number) => {  if (audioDuration.value === 0) return;  playProgress.value = val;  audioRef.value.currentTime = (playProgress.value / 100) * audioDuration.value;  audioCurrent.value = audioRef.value.currentTime;};// 文字展示const handleText = async () => {  showText.value = !showText.value;};// 音频加载完毕的回调const onCanplay = () => {  audioDuration.value = audioRef?.value.duration || 0;};const onPlay = async () => {  // 音频播放完后,重新播放  if (playProgress.value === 100) audioRef.value.currentTime = 0;  await audioRef.value.play();  playStatus.value = true;  audioDuration.value = audioRef.value.duration;  timeInterval.value = setInterval(() => {    audioCurrent.value = audioRef.value.currentTime;    playProgress.value = (audioCurrent.value / audioDuration.value) * 100;    if (playProgress.value === 100) onPause();  }, 100);};const onPause = () => {  audioRef.value.pause();  playStatus.value = false;  clearInterval(timeInterval.value);};const onChangeSpeed = (value: number) => {  activeSpeed.value = value;  // 设置倍速  audioRef.value.playbackRate = value;  speedVisible.value = false;};const onHandleSpeed = () => {  speedVisible.value = !speedVisible.value;};// 音频播放时间换算const transTime = (value: number) => {  return `${Math.floor(value / 3600) > 9 ? Math.floor(value / 3600) : `0${Math.floor(value / 3600)}`}:${moment({    m: moment.duration(value, 'seconds').minutes(),    s: moment.duration(value, 'seconds').seconds(),  }).format('mm:ss')}`;};</script><style lang="less" scoped>.progress {  ::v-deep .sp-slider__button-wrapper {    width: 20px;    height: 20px;    margin-top: 8px;  }  ::v-deep .sp-slider__button {    width: 12px;    height: 12px;    background-color: #4974f5;  }}</style>

3 使用尝试

在外层父组件中使用如下:

先引入组件

<script setup lang="ts">import AudioBase from '@/layouts/components/baseComponents/AudioBase.vue';</script>

然后直接使用

<div bg-white p-10 rounded-5>   播放组件:   <audio-base></audio-base></div>


点击全文阅读


本文链接:http://zhangshiyu.com/post/191858.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1