Vue3自定义封装音频播放组件(带拖拽进度条)

Vue3自定义封装音频播放组件(带拖拽进度条)

描述

该款自定义组件可作为音频、视频播放的进度条,用于控制音频、视频的播放进度、暂停开始、拖拽进度条拓展性极高。

实现效果

在这里插入图片描述

具体效果可以根据自定义内容进行位置调整

项目需求
  1. 有播放暂停按钮
  2. 进度条可以跟随播放丝滑更新
  3. 有当前播放时间和总时间可以根据播放更新当前时间
  4. 可以点击进度条的某一处跳转到指定处进行播放
技术栈

vue3+elementUI || elementPlus || vant

功能实现
  <template>
  <div class="audio_wrap_content" :style="[{ backgroundColor: bgColor }]">
    <audio ref="audio" @play="playFunc" @pause="pauseFunc" @timeupdate="timeupdateFunc"
      @loadedmetadata="onLoadedmetadata" @ended="handleEnd">
      <source :src="audioSrc" />
    </audio>
    <div class="cudio_control_content">
      <img @click="startPlayOrPause" class="state_img" :src="audio.playing ? stopImg : playImg" alt="" />

      <div class="slider">
        <span>{{ formattedCurrentTime }}</span>
        <div><el-slider v-model="sliderTime" :show-tooltip="false" @change="onChange"></el-slider></div>
        <span>{{ formattedMaxTime }}</span>
      </div>
    </div>
  </div>
</template>

<script>
function formatTime(second) {
  let m = parseInt(second / 60);
  let s = parseInt(second % 60);
  let formatTime = "";
  if (second == 0) {
    return "0'00''";
  }
  if (m == 0) {
    if (s >= 10) {
      formatTime = "0'" + s + "''";
    } else {
      formatTime = "0'0" + s + "''";
    }
  } else {
    if (s >= 10) {
      formatTime = m + "'" + s + "''";
    } else {
      formatTime = m + "'0" + s + "''";
    }
  }
  return formatTime;
}
export default {
  name: "AudioPlay",
  props: {
    bgColor: {
      type: String,
      default: "rgba(255,255,255,0.15)",
    },
    audioSrc: {
      type: String,
      default: require("@/assets/music/offer_des.mp3"),
    },
    themeColor: {
      type: String,
      default: "#ffb900",
    },
  },
  data() {
    return {
      value1: 1,
      playImg: require("@/assets/images/play.png"),
      stopImg: require("@/assets/images/stop.png"),
      sliderTime: 0,
      audio: {
        maxTime: 0,
        currentTime: 0,
        playing: false,
      },
    };
  },
  computed: {
    formattedCurrentTime() {
      return formatTime(this.audio.currentTime);
    },
    formattedMaxTime() {
      return formatTime(this.audio.maxTime);
    },
  },
  methods: {
    play() {
      console.log("触发 播放");
      this.$refs.audio.play();
    },
    pause() {
      this.$refs.audio.pause();
    },
    playFunc() {
      this.audio.playing = true;
    },
    pauseFunc() {
      this.audio.playing = false;
    },
    handleEnd() {
      this.sliderTime = 0;
      this.audio.playing = false;
      this.audio.currentTime = 0;
    },
    timeupdateFunc(res) {
      this.audio.currentTime = res.target.currentTime;
      this.sliderTime = parseInt(
        (this.audio.currentTime / this.audio.maxTime) * 100
      );
    },
    onLoadedmetadata(res) {
      console.log(111, "首次加载完成");
      this.audio.maxTime = parseInt(res.target.duration);
    },
    startPlayOrPause() {
      console.log("bof", "暂停-播放");
      this.audio.playing ? this.pause() : this.play();
    },
    onChange(value) {
      console.log(value, "values");
      this.$refs.audio.currentTime = parseInt(
        (value / 100) * this.audio.maxTime
      );
    },
  },
};
</script>

<style scoped lang="less">
.audio_wrap_content {
  height: 26px;
  border-radius: 15px;
}

.cudio_control_content {
  margin: 0 auto;
  width: 90%;
  height: 100%;
  display: flex;

  .slider {
    flex: 1;
    width: 100%;
    display: flex;
    align-items: center;

  }

  .slider div {
    flex: 1;
  }

  .slider span {
    margin: 0 15px;
    font-size: 10px;
    color: rgba(34, 34, 34, 0.3);
  }

  justify-content: space-between;
  align-items: center;

  .state_img {
    width: 18px;
    height: 18px;
    margin-right: 15px;

  }

  .custom-button {
    width: 8px;
    background-color: #ffb900;
    height: 8px;
    border-radius: 8px;
  }

  .state_time {
    font-family: "BIGJOHN";
    font-size: 10px;
    color: rgba(34, 34, 34, 0.3);
    margin-right: 3px;
    margin-left: 3px;
  }

}
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

特征融合篇 | YOLOv8改进之利用ASF-YOLO重构特征融合层 | 助力小目标检测

前言:Hello大家好,我是小哥谈。ASF-YOLO是一个目标检测模型,它基于YOLOv3算法,并引入了ASF(Anchor-Free Spatial Attention)模块。ASF模块可以自适应地学习特征图上每个位置的不同感受野,提高了模型对于小目标的检测能力。相比于YOLOv3,ASF-YOLO在保持准确率的同时大大…

3d里如何做螺旋状模型?---模大狮模型网

螺旋状模型在3D设计中常常被运用&#xff0c;不仅可以用于创造独特的装饰品和艺术品&#xff0c;还可以用于建筑设计、工程模拟等领域。然而&#xff0c;对于初学者而言&#xff0c;如何在3D软件中创建螺旋状模型可能是一个挑战。在本文中&#xff0c;我们将分享几种简单而有效…

Linux diff命令(比较两个文件或目录的内容差异)

文章目录 Linux diff 命令详解教程基本用法比较文件输出解释 递归比较&#xff08;-r&#xff09;示例代码 控制输出格式统一格式&#xff08;-u&#xff09;上下文格式&#xff08;-c&#xff09; 高级选项忽略所有空白差异&#xff08;-w&#xff09;仅报告文件是否不同 Linu…

【Web】CTFSHOW 单身杯 题解

目录 web签到 easyPHP 姻缘测试 web签到 用data协议包含php标签闭合 payload: filedata://text/plain,<?php system($_GET[1]);?>>?;)]1[TEG_$(metsys php?<,nialp/txet//:atadeasyPHP 一眼awk命令执行 payload: cmdawk&param{system("ta…

MySQL数据库连接 提示错误 10060

错误现象 Cant connect to server on (10060) 有3个原因&#xff1a; 1、防火墙没有关闭 &#xff08;注意如果配置开放了3306端口&#xff0c;则不可以关闭防火墙&#xff0c;需删除规则以后才能关闭&#xff09; 关闭防火墙&#xff08;1次&#xff09;systemctl stop fir…

数据结构_顺序表中基本操作的实现_代码

学习笔记&#xff0c;仅供参考 1.头文件 2.初始化 3.增加值 4.根据下标取值 5.查找 6.插入 7.删除 8.动态增加数组的长度 9.所有代码 10.运行结果 1.头文件 //顺序表的实现——动态分配 #include<stdio.h> #include<stdlib.h> #define InitSize 10 type…

Arduino-点亮TFT触摸屏一

Arduino-点亮TFT触摸屏一 1.概述 这篇文章主要介绍Arduino操作TFT触摸屏入门操作&#xff0c;通过SPI通信协议方式点亮TFT触摸屏。 2.硬件电路 2.1.硬件列表 名称数量Arduino Uno12.8" TFT彩色液晶触摸屏模块&#xff08;ILI9431&#xff09;110K 电阻5面包板1杜邦线…

ICode国际青少年编程竞赛- Python-3级训练场-if语句入门

ICode国际青少年编程竞赛- Python-3级训练场-if语句入门 1、 for i in range(5):Spaceship.step(i 1)Spaceship.turnRight()if i 1:Dev.step(1)Dev.step(-1)2、 for i in range(4):Dev.step(2)if i ! 1:Dev.turnLeft()Dev.step(3)Dev.step(-3)Dev.turnRight()3、 for i…

springboot3项目练习详细步骤(第三部分:文章管理模块)

目录 发布文章 接口文档 业务实现 自定义参数校验 项目参数要求 实现思路 实现步骤 文章列表(条件分页) 接口文档 业务实现 mapper映射 更新文章 接口文档 业务实现 获取文章详情 接口文档 业务实现 删除文章 接口文档 业务实现 文章管理业务表结构…

OpenHarmony实战开发——WLAN驱动框架介绍及适配方法

1. WLAN 驱动框架概述 WLAN 是基于 HDF(Hardware Driver Foundation)驱动框架开发的模块&#xff0c;该模块可实现跨操作系统迁移、自适应器件差异、模块化拼装编译等功能。从而降低 WLAN 驱动开发的难度&#xff0c;减少 WLAN 驱动移植和开发的工作量。 本文主要分析 WLAN 驱…

gif压缩大小但不改变画质怎么做?分享5个压缩GIF原理~

GIF&#xff08;图形互换格式&#xff09;是网络上广泛使用的一种图像格式&#xff0c;因其支持动画而备受欢迎。然而&#xff0c;随着动画越来越复杂和高分辨率&#xff0c;GIF 文件大小也随之增加&#xff0c;可能导致加载速度变慢和带宽消耗增加。在这篇文章中&#xff0c;我…

easypoi动态表头导出数据

需求&#xff1a;动态导出某年某月用户和用户评分数据信息&#xff0c;表头(序号、姓名、用户姓名)&#xff0c;数据(所有用户对应的评分以及平均分)&#xff1b; 分析&#xff1a;1、表头除过序号、姓名&#xff0c;用户姓名要动态生成&#xff1b; 2、用户评分信息要和表头中…

Nginx+GateWay

目录 Nginx nginx如何配置负载均衡 负载均衡有哪些策略 1、轮询&#xff08;默认&#xff09; 2、指定权重 3、ip_hash&#xff08;客户端ip绑定&#xff09; 4、least_conn&#xff08;最少连接&#xff09; 5、fair 6、url_hash Nginx为什么效率高 gateway 使用gat…

Lobe Chat–在线AI对话聊天机器人,一键部署,免费开源

Lobe Chat 现代化设计的开源 ChatGPT/LLMs 聊天应用与开发框架 支持语音合成、多模态、可扩展的&#xff08;function call&#xff09;插件系统 一键免费拥有你自己的 ChatGPT/Gemini/Claude/Ollama 应用 项目演示 支持多种模型接口 支持语音输入输出 支持云端同步 丰富多彩非…

1013: 哈希表(开放定址法处理冲突)

解法&#xff1a; 线性探测是一种解决哈希冲突的方法&#xff0c;当发生哈希冲突时&#xff0c;它会依次往后查找空的槽位&#xff0c;直到找到一个空的槽位或者达到数组的末尾。 下面是处理哈希冲突的线性探测的步骤&#xff1a; 创建一个哈希表&#xff0c;里面包含一定数量的…

Ps 滤镜:视频

Ps菜单&#xff1a;滤镜/视频 Filter/Video “视频”滤镜子菜单中包含了“NTSC 颜色”和“逐行”两个滤镜。 这两个滤镜都是针对视频和电视播放的特定需求设计的。 “逐行”滤镜主要解决交错视频的视觉问题&#xff0c;而“NTSC 颜色”滤镜则确保色彩在电视播放时的兼容性和准确…

一文带你了解OSPF 七种LSA类型,很全!

大家好&#xff0c;今天我们 带大家了解一下OSPF的七种LSA类型。 在OSPF&#xff08;开放式最短路径优先&#xff09;协议中&#xff0c;LSA&#xff08;链路状态通告&#xff09;是一种至关重要的数据格式&#xff0c;专门用于描述路由信息。它包含了路由器或网络的各种状态信…

编写一个C#程序,实现音乐文件的播放功能

一、作业要求 要求1&#xff1a; 1. 程序应能够读取MP3文件&#xff0c;并播放其中的音频。 2. 程序应能够处理可能出现的异常&#xff0c;如文件不存在、文件读取错误等。 3. 程序应具有良好的用户界面&#xff0c;方便用户进行操作。 4. 程序应具有良好的兼容性&#xf…

VK6932 SOP32数码屏驱动IC抗干扰数显芯片高稳定LED驱动 原厂FAE支持

产品型号&#xff1a;VK6932 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SOP32 工程服务&#xff0c;技术支持&#xff01; 概述 VK6932是一种数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有3线串行接口、数据锁存器、LED 驱动等电路。SEG脚接LED阳…

【Python】selenium爬虫常见用法和配置,以及常见错误和解决方法

欢迎来到《小5讲堂》 这是《Python》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言无执行文件代码报错信息错误路径手动下载自动下载 选项配置Ch…