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

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

描述

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

实现效果

在这里插入图片描述

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

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

vue2/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="state_time" style="marginRight:5px">{{audio.currentTime | formatSecond}}</div>
            <div class="slider">
                <el-slider v-model="sliderTime" :show-tooltip="false" @change="onChange"></el-slider>
            </div>
        	<!-- 这块代码是移动端的vant组件库可用于移动端H5 (如要用此代码则需要将css中的.slider:flex:1去掉 并将slider类名div注释即可) -->
            <!-- <van-slider
                v-model="sliderTime"
                bar-height="1px"
                active-color="#ffb900"
                button-size="4px"
                @change="onChange"
                >
                <template #button>
                    <div class="custom-button"></div>
                </template>
            </van-slider> -->

        <div class="state_time" style="marginLeft:5px">{{audio.maxTime | formatSecond}}</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 /* 音频当前处于播放/暂停状态 */,
        },
      };
    },
    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();
      },
      /* 拖动进度条,改变当前时间 value是进度条改变时的回调函数的参数 值为0~100之间,需要换算成实际时间 */
      onChange(value){
        console.log(value,'values');
        this.$refs.audio.currentTime = parseInt(value / 100 * this.audio.maxTime)
        // console.log(this.$refs.audio.currentTime , 'this.$refs.audio.currentTime ');
      }
    },
    filters: {
      formatSecond(second=0){
        return formatTime(second)
      }
    },
  };
  </script>
  
  <style scoped lang="less">
  .audio_wrap_content {
    // width: 180px;
    height: 26px;
    border-radius: 15px;
    // transform: translateX(-25px);
  }
  
  .cudio_control_content {
    margin: 0 auto;
    width: 90%;
    height: 100%;
    display: flex;
    .slider{
        flex:1
    }
    justify-content: space-between;
    align-items: center;
    
    .state_img {
      width: 18px;
      height: 18px;
    }
  
    .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>

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

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

相关文章

51单片机软件环境安装

keli5的安装 把CID放到破解程序中 破解程序会给一串数字然后填到那个框中 驱动程序的安装 安装完了以后 设备管理器会出现这个 同时c盘会出现这个文件夹

巨量千川的投放技巧,一站式全自动千川投流工具(抖音玩家必备)

随着抖音平台的快速发展&#xff0c;越来越多的品牌和广告商意识到抖音的潜力&#xff0c;并希望能够通过投放广告来获取更多的曝光和用户参与。在这个过程中&#xff0c;巨量千川成为了抖音玩家必备的一站式全自动千川投流工具&#xff0c;为广告商提供了投放技巧&#xff0c;…

word-快速入门

1、熟悉word界面 2、word排版习惯 3、排版文本基本格式 1、word界面 选项卡 功能组 点击功能组右下角小三角可以开启完整功能组&#xff0c;获得启动器 软件右上角有功能显示折叠按钮 2、排版好习惯 &#xff08;1&#xff09;随时保存 &#xff08;2&#xff09;规范文件命…

408算法题专项-2015

题目&#xff1a; 分析&#xff1a;时间复杂度尽可能高效&#xff0c;提示可能存在一种空间换时间的算法 思路一&#xff1a;空间换时间 思考&#xff1a;开数组储存结点数据域&#xff0c;对于只出现一次或多次出现第一次的&#xff0c;保留&#xff0c;对于多次出现的&…

流程详解!2024年成都市发明专利申请流程及各阶段操作要点

一、受理阶段 时间期限&#xff1a; 电子申请2天内&#xff0c;纸质申请当天现场提交&#xff0c;邮寄约为半月。 申请人&#xff1a; 1. 委托专利代理机构&#xff0c;签订委托代理协议和保密协议等&#xff1b; 2. 提供原始技术资料和个人以及单位信息等&#xff1b; 3…

片冰机工作原理

片冰机工作原理 1、制冰用的水需要加盐(行话叫做加药)至于多少量。看制冰量多少调制泵(柱塞泵)自动调整。 2、制冰机主体分两腔体外腔体内盘的一定密度的铜管。专业术语叫(蒸发腔)就是俗话讲的制冷的东西。 3、外腔体内是一个很规则的圆不锈钢腔体&#xff0c;中心有一三叶刮…

基于Django图像识别系统毕业设计(付源码)

前言&#xff1a;Django是一个由Python编写的具有完整架站能力的开源Web框架&#xff0c;Django本身基于MVC模型&#xff0c;即Model&#xff08;模型&#xff09;View&#xff08;视图&#xff09; Controller&#xff08;控制器&#xff09;设计模式&#xff0c;因此天然具有…

零售数据分析之连带销售分析怎么做

连带销售是指顾客在购买某款产品后&#xff0c;通常会顺手也买上另一款产品。这种情况在超市零售中屡见不鲜&#xff0c;因此通常来说在做超市零售数据分析时&#xff0c;都需要做一个详尽的连带销售分析。那么做零售数据分析中的连带销售分析&#xff0c;要计算分析哪些指标&a…

MBR与GPT分区表

文章目录 MBR分区表MBR分区表结构MBR分区表项查看U盘的分区表信息查看系统中所有磁盘的分区类型获取分区表信息 GPT分区表保护性MBRGPT分区表头格式GPT分区表项格式分区类型分区属性分区表项内容 MBR分区表 CHS &#xff1a;磁头&#xff08;Heads&#xff09;、柱面(Cylinder…

AH8651-220V转3.3V低成本方案

本篇文章将介绍一种220V转3.3V低成本方案&#xff0c;该方案采用AH8651芯片&#xff0c;无需外接电感&#xff0c;具有高效率的智能控制、宽广的交流输入范围、内置过流保护、欠压保护和过热自动关断等功能。AH8651可以通过SEL引脚选择输出电压&#xff0c;启动时通过内部高压电…

【连连国际注册/登录安全分析报告】

连连国际注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨…

Numpy的数组操作

文章目录 数组的创建创建全0的二维数组a(3,3)全1的二维数组b&#xff08;3,4&#xff09;随机数二维数数组c&#xff08;2,3&#xff09;效果截图 数组的属性查看b数组的维度查看b数组元素的个数效果截图 数组的维度操作将数组c的行变列&#xff0c;返回最后一个元素返回数组c第…

vue3打开页面后文本框自动获得焦点

字符串写法 <script setup> import { ref, onMounted } from vue import ./index.cssconst input ref(null)onMounted(() > {input.value.focus() }) </script><template><div class"m-home-wrap"><input ref"input" />…

用Rust打印杨辉三角

一、杨辉三角是什么&#xff1f; 杨辉三角是一个著名的数学图形&#xff0c;它展示了二项式系数的排列方式。 杨辉三角是一种将二项式系数以三角形阵列排列的数学图形&#xff0c;具有丰富的历史和数学意义。 杨辉三角的历史起源可以追溯到中国南宋时期&#xff0c;由数学家杨辉…

「 网络安全常用术语解读 」漏洞利用预测评分系统EPSS详解

1. 概览 EPSS&#xff08;Exploit Prediction Scoring System&#xff0c;漏洞利用预测评分系统&#xff09; 提供了一种全新的高效、数据驱动的漏洞管理功能。EPSS是一项数据驱动的工作&#xff0c;使用来自 CVE 的当前威胁信息和现实世界的漏洞数据。 EPSS 模型产生 0 到 1&…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-15-GPIO中断控制实验

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

大语言模型LLM原理篇

大模型席卷全球&#xff0c;彷佛得模型者得天下。对于IT行业来说&#xff0c;以后可能没有各种软件了&#xff0c;只有各种各样的智体&#xff08;Agent&#xff09;调用各种各样的API。在这种大势下&#xff0c;笔者也阅读了很多大模型相关的资料&#xff0c;和很多新手一样&a…

电脑ip地址设置成什么比较好

随着信息技术的快速发展&#xff0c;IP地址已成为电脑在网络世界中的“身份证”。它不仅是电脑在网络中进行通信的基础&#xff0c;也直接关系到网络连接的稳定性、安全性和效率。然而&#xff0c;面对众多IP地址设置选项&#xff0c;许多用户可能会感到困惑。那么&#xff0c;…

图形网络的自适应扩散 笔记

1 Title Adaptive Diffusion in Graph Neural Networks&#xff08;Jialin Zhao、Yuxiao Dong、Ming Ding、Evgeny Kharlamov、Jie Tang&#xff09;【NIPS 2021】 2 Conclusion The neighborhood size in GDC is manually tuned for each graph by conductin…

docker-compose集成elasticsearch7.17.14+kibana7.17.14

1.docker和compose版本必须要高 2.准备ik分词器&#xff08;elasticsearch-analysis-ik-7.17.14&#xff09;&#xff0c;下面会用到 https://github.com/infinilabs/analysis-ik/releases?page2 3.配置es-compose.yml&#xff08;切记映射容器内路径不能更改,es和kibana服务…