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

6 篇文章 0 订阅
3 篇文章 0 订阅

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

描述

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

实现效果

在这里插入图片描述

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

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

vue2+elementUI || elementPlus || vant
vue3去掉了filter API

功能实现
  <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>
  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值