基于vue3和audio封装的简易音频播放器

样式如图所示
在这里插入图片描述

<template><div class="audio-player"><div class="player_top" flex-ac  flex-justify-between ><div class="fileName  genericTitle" fs-28 l-height-32 height-64 pr-42 flex-ac><span class="text-line-2">{{ fileName }}</span></div><div class="play_btn"><div class="toPlay" width-60 height-60 v-if="!playStatus" @click="onPlay"></div><div class="toStop" width-60 height-60 v-else @click="onPause"></div></div></div><div class="player_time" fs-14 mt-13 mb-8 flex  flex-justify-between><span class="play_audioCurrent" style="color:#1e62d9"> {{ transTime(audioCurrent) }} </span><span class="play_audioDuration" style="color:#A5A5A5"> {{ transTime(audioDuration) }} </span></div><div class="play_progress" pl-13 pr-13><el-slider v-model="playProgress" :show-tooltip="false" @input="onProgressChange" /></div></div><audio ref="audioRef" :src="url" @canplay="onCanplay" @timeupdate="updateProgress" @ended="playEnd" />
</template><script setup lang="ts">
import { ref, onBeforeMount, onUnmounted, onMounted, watch, nextTick } from 'vue';const props = defineProps({// 音频地址url: {type: String,required: true},// 音频名称fileName: {type: String,required: false}
});
const emits = defineEmits(['play', 'timeupdate']);
watch(() => props.url,newVal => {if (newVal) {nextTick(() => {initAudio();});}}
);const speedVisible = ref<boolean>(false); // 设置音频播放速度弹窗
const audioRef = ref<HTMLAudioElement | null>(null); // 音频标签对象
const activeSpeed = ref(1); // 音频播放速度
const audioDuration = ref(0); // 音频总时长
const audioCurrent = ref(0); // 音频当前播放时间
const audioVolume = ref(1); // 音频声音,范围 0-1
const playStatus = ref<boolean>(false); // 音频播放状态:true 播放,false 暂停
const playProgress = ref(0); // 音频播放进度const initAudio = () => {if (audioRef.value) {audioRef.value.load();playStatus.value = false;playProgress.value = 0;audioRef.value.src = props.url;}
};// 音频加载完毕的回调
const onCanplay = () => {audioDuration.value = audioRef?.value.duration || 0;
};
const onPlay = async () => {// 音频播放完后,重新播放if (transTime(audioCurrent.value) === transTime(audioDuration.value)) audioRef.value.currentTime = 0;await audioRef.value.play();playStatus.value = true;audioDuration.value = audioRef.value.duration;emits('play');
};
const onPause = () => {audioRef.value.pause();playStatus.value = false;
};
// const onChangeSpeed = (value: number) => {
//   activeSpeed.value = value;
//   // 设置倍速
//   audioRef.value.playbackRate = value;
//   speedVisible.value = false;
// };
// const onHandleSpeed = () => {
//   speedVisible.value = !speedVisible.value;
// };
// // 设置声音
// const onSetVolume = (value: number) => {
//   audioRef.value.volume = value;
//   audioVolume.value = value;
// };
// 音频播放时间换算
const transTime = (value: number) => {let time = '';let h = parseInt(String(value / 3600));value %= 3600;let m = parseInt(String(value / 60));let s = parseInt(String(value % 60));if (h > 0) {time = formatTime(h + ':' + m + ':' + s);} else {time = formatTime(m + ':' + s);}return time;
};
// 格式化时间显示,补零对齐
const formatTime = (value: string) => {let time = '';let s = value.split(':');let i = 0;for (; i < s.length - 1; i++) {time += s[i].length == 1 ? '0' + s[i] : s[i];time += ':';}time += s[i].length == 1 ? '0' + s[i] : s[i];return time;
};
const onTimeUpdate = () => {if (audioRef.value) {audioCurrent.value = audioRef.value.currentTime;const progressPercentage = (audioRef.value.currentTime / audioRef.value.duration) * 100;emits('timeupdate', {currentTime: audioCurrent.value,duration: audioDuration.value,progress: progressPercentage});}
};
const onProgressChange = (value: number) => {// if (!value) {//   return;// }console.log(value,'value');audioRef.value.currentTime = (value / 100) * audioDuration.value;
};
const updateProgress = (e) => {// console.log(e,'e');onTimeUpdate();const value = e.target.currentTime / e.target.duration;if (audioRef.value.play) {playProgress.value = value * 100;audioCurrent.value = audioRef.value.currentTime;}
};
const playEnd = () => {playStatus.value = false;
};
// onMounted(() => {
//   initAudio();
// });
onBeforeMount(() => {});
onUnmounted(() => {
});
</script><style lang="scss" scoped>
.audio-player {width: 100%;height: 193px;background: #ffffff;border: 10px solid #c5e9ff;border-radius: 20px;padding: 26px 26px 0 26px;box-sizing: border-box;display: flex;flex-direction: column;align-items: center;.player_top{width: 100%;}.player_time{width: 100%;}.play_progress{width: 100%;::v-deep(.el-slider__runway){height: 10px;border-radius: 6px;background-color: #e5e5e5;.el-slider__bar{height: 10px;border-radius: 6px;background: linear-gradient(270deg,#53c0ff, #3870ff);}.el-slider__button-wrapper{top: -13px;}.el-slider__button{width: 26px;height: auto !important;aspect-ratio: 1 !important;background-color: #1E62D9;border: px2vw(4) solid #ffffff;box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.16);}}}.play-icon {width: 60px;height: 60px;// margin-right: 7px;cursor: pointer;}.play-time {}.play-progress {width: 160px;height: 4px;background-color: #323547;box-shadow: inset 0px 1px 0px 0px #20222d;border-radius: 2px;margin-right: 16px;position: relative;.play-current-progress {height: 4px;background: #00e5ff;border-radius: 2px;position: absolute;top: 0;left: 0;}}.play-voice {width: 20px;height: 20px;margin-right: 14px;cursor: pointer;}.play-speed {cursor: pointer;color: #00e5ff;}.fileName {}.play_btn {cursor: pointer;.toPlay {background: url('@/assets/images/icon_play_audio@2x.png') no-repeat;background-size: 100% 100%;background-origin: border-box;background-clip: content-box;&:hover {background: url('@/assets/images/icon_play_audio_h@2x.png') no-repeat;background-size: 100% 100%;background-origin: border-box;background-clip: content-box;}}.toStop {background: url('@/assets/images/icon_stop_audio@2x.png') no-repeat;background-size: 100% 100%;background-origin: border-box;background-clip: content-box;&:hover {background: url('@/assets/images/icon_stop_audio_h@2x.png') no-repeat;background-size: 100% 100%;background-origin: border-box;background-clip: content-box;}}}
}
</style>

使用

              <AudioPlayer:url="currentResource?.resourceUrl":fileName="currentResource?.resourceName"@play="playMedia"@timeupdate="toUpdatePlayMediaTime"/>// 音视频触发播放
const playMedia = () => {// console.log(currentResource.value, 'playMedia开始播放');
};
// 音视频播放进度
const toUpdatePlayMediaTime = e => {if (e.progress > 85 && currentResource.value.completeStatus === 0) {// 音视频播放进度大于85则该资源标记为学习完成}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/52129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

维护和升级LabVIEW程序

在维护和升级LabVIEW程序时&#xff0c;需要全面考虑代码的现状和未来的需求。以下是各个方面的详细注意事项&#xff0c;以确保程序能够在稳定性和性能方面得到提升。 1. 理解现有代码: 深入代码分析: 仔细阅读现有的代码&#xff0c;了解其逻辑结构、数据流、和控制流程。关注…

中国大模型平台市场份额最新排名Top5!场景化应用昭示新蓝海

8月21日&#xff0c;IDC&#xff08;国际数据公司&#xff09;首次发布了《中国大模型平台市场份额&#xff0c;2023&#xff1a;大模型元年 —— 初局》。数据显示&#xff0c;2023年中国大模型平台及相关应用市场规模达17.65亿元人民币。 在过去的2023年&#xff0c;行业对于…

会话跟踪方案:Cookie Session Token

什么是会话技术&#xff1f; Cookie 以登录为例&#xff0c;用户在浏览器中将账号密码输入并勾选自动登录&#xff0c;浏览器发送请求&#xff0c;请求头中设置Cookie&#xff1a;userName:张三 ,password:1234aa &#xff0c;若登录成功&#xff0c;服务器将这个cookie保存…

「数组」数组双指针算法合集:二路合并|逆向合并|快慢去重|对撞指针 / LeetCode 88|26|11(C++)

目录 概述 1.二路合并 思路 复杂度 Code 2.逆向合并 思路 复杂度 Code 3.快慢去重 思路 复杂度 Code 4.对撞指针 思路 复杂度 Code 总结 概述 数组的线性枚举是我们学习编程时遇到的第一种枚举手段。但是它看起来有点愚蠢&#xff1a;只有一个索引i承担全部…

学生党蓝牙耳机哪个牌子性价比高?推荐四款内行精选百元耳机!

作为没有什么经济来源的学生党&#xff0c;唯一来钱的途径就是家里给的生活费。所以在选择一款蓝牙耳机时就很纠结&#xff0c;那么首先你得清楚学生党的购物习性&#xff0c;因为大部分学生党在买东西时因为经济能力问题&#xff0c;主要追求的还是性价比&#xff0c;可以在实…

IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀放大器

IP-DAR-250、IP-DAR-43C-L、IP-DAR-43C-H、IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀 EE-PRB、EE-PRD比例压力阀 EE-P2G、ET-P2S、EB-P2A、EE-P2A、ET-P2A、EE-P2H、EG-F2A、EU-F2A比例流量阀 EF-F3G、EU-F3G比例压力补偿流量阀 EQ-S4M、EG-S4M、EQ…

DVWA靶场通关(CSRF)

CSRF 是跨站请求伪造&#xff0c;是指利用受害者尚未失效的身份认证信息&#xff08;cookie、会话等&#xff09;&#xff0c;诱骗其点击恶意链接或者访问包含攻击代码的页面&#xff0c;在受害人不知情的情况下以受害者的身份向&#xff08;身份认证信息所对应的&#xff09;服…

eNSP 华为ACL配置

华为ACL配置 需求&#xff1a; 公司保证财务部数据安全&#xff0c;禁止研发部门和互联网访问财务服务器&#xff0c;但总裁办不受影响 R1&#xff1a; <Huawei>sys [Huawei]sys Router1 [Router1]undo info-center enable [Router1]int g1/0/0 [Router1-GigabitEth…

开放式耳机为什么性价比高?四款开放式蓝牙耳机排行榜前十名推荐

如果说需要高性价比的蓝牙耳机推荐的话&#xff0c;我会比较推荐开放式耳机&#xff0c;因为这类的耳机产品价格普遍都不会太高&#xff0c;但配置却都很好。那除了性价比高&#xff0c;开放式耳机还有其他好的地方吗&#xff1f;那当然是有的&#xff0c;对于蓝牙耳机来说&…

HTML+JS谁是卧底游戏

先说一句&#xff1a;一段时间没发文章&#xff0c;好多僵尸粉关注我&#xff0c;这CSDN&#x1f620; 主要功能 玩家设置&#xff1a;在游戏开始前&#xff0c;输入总人数、卧底人数和白板人数。系统会自动计算出剩下的平民人数&#xff0c;并随机分配身份。 身份查看&#…

DHCP协议-CSP认证

文章目录 DHCP协议 DHCP协议 stringstream的用法 应用实践 #include<bits/stdc.h>using namespace std;signed main() {string s"wo shi wwl, also wlw";stringstream ss;ss<<s;while(ss>>s){if(s[s.size()-1],) s[s.size()-1] ;cout<<s<…

授权cleanmymac访问全部磁盘 Mac授权访问权限 cleanmymac缺少权限

CleanMyMac是Mac系统下的一款专业的苹果电脑清理软件&#xff0c;同时也是一款优秀的电脑系统管理软件。它能有效清理系统垃圾&#xff0c;快速释放磁盘内存&#xff0c;缓解卡顿现象&#xff0c;保障系统顺畅地运行。 全磁盘访问权限&#xff0c;就好比机场内进行的安全检查。…

【AD9361 数字基带】多片基带内FPGA补偿 I/Q Rotation

I/Q 旋转 Rotation 在许多多通道射频系统中&#xff0c;如 AD-FMCOMMS5&#xff0c;甚至在 AD-FMCOMMS2、AD-FMCOMMS3 上&#xff0c;都需要测量或校正两个复数 &#xff08;I/Q&#xff09; RF 信号之间的相位差。 从纯粹的数学描述来看&#xff0c;单个正弦波没有相位&…

Godot《躲避小兵》实战之游戏开始界面制作

我们的游戏还需要用户可操作的界面&#xff0c;比如开始游戏&#xff0c;退出以及显示分数等UI界面。 创建新场景&#xff0c;点击“其他节点”按钮&#xff0c;然后添加一个 CanvasLayer 节点并命名为 HUD。“HUD”是“heads-up display”&#xff08;游戏信息显示&#xff0…

计算机网络——运输层(进程之间的通信、运输层端口,UDP与TCP、TCP详解)

运输层协议概述 进程之间的通信 运输层向它上面的应用层提供通信服务。 当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时&#xff0c;都要使用协议栈中的运输层&#xff1b;而网络核心部分中的路由器在转发分组时只用到下三层的功能。 Q1&#xff1a;我们…

最全Java集合分片处理!!! Java 中 List 分片的 7种方法

文章目录 Java 中 List 分片的 7种方法业务需求背景实现方法方法一&#xff1a;最基本的 for 循环实现方法二&#xff1a;利用 List 的 subList() 方法方法三&#xff1a;stream 流操作 filter 方法过滤方法四&#xff1a;使用 Google Guava 的 Lists.partition 方法方法五&…

【计算机三级-数据库技术】操作题大题(第六套)

第六套操作题 第46题 假定要建立一个学校科研项目管理的信息系统&#xff0c;需要管理如下信息&#xff1a; 教师&#xff1a;教师编号、教师姓名&#xff1b; 项目&#xff1a;项目编号、项目名称、资助额&#xff1a; 学生&#xff1a;学生编号、学生姓名、学位&#xff0c…

跟李沐学AI:转置卷积

定义 卷积不会增大输入的高宽&#xff0c;通常卷积层后高宽不变或减半。转置卷积则可以用来增大输入的宽高。 转置卷积是一种卷积&#xff0c;它将输入和核进行了重新排列&#xff0c;通常用作上采用。 如果卷积将输入从变为&#xff0c;同样超参数的情况下&#xff0c;转置…

集团数字化转型方案(十二)

集团数字化转型方案致力于通过构建一个集成化的数字平台&#xff0c;全面应用大数据分析、人工智能、云计算和物联网等前沿技术&#xff0c;推动业务流程、管理模式和决策机制的全面升级。该方案将从业务流程的数字化改造开始&#xff0c;优化资源配置&#xff0c;提升运营效率…

yolov8 出现loss 为nan

原因&#xff1a; 混合精度训练是一种通过同时使用 FP16 和 FP32 精度来加速深度学习训练的技术。它可以在不损失模型性能的情况下,显著减少训练时间和内存使用。下面是关于混合精度训练的一些解释: 1. 原理 混合精度训练利用了 FP16 (16位浮点)和 FP32 (32位浮点)的不同特性。…