封装一个audio音频组件,包含前进后退及进度条等

因为项目里有这个需求,所以我参考别人的代码,加上自己的理解,把audio组件封装了一下,当然这个是最基本的,具体的还得根据不同的项目需求来改造。

来看完整代码(在vue中封装的):

<template>
  <!-- 录音播放区域 -->
  <div>
    <div class="h4-meeting">Meeting</div>
    <audio
      @canplay="getDuration"
      controls
      @timeupdate="updateTime"
      v-show="false"
      ref="audio"
      :src="audioSrc"
    />
    <div class="card">
      <div
        class="progress"
        ref="progress"
        @click="clickProgress"
        @mouseup="handleMouseup"
      >
        <div class="currentProgress" ref="currentProgress">
          <span class="circle" ref="circle" @mousedown="handleMousedown"></span>
        </div>
      </div>
      <div class="time">
        <span class="startTime">{{ currentDuration }}</span>
        <span class="endTime">{{ duration }}</span>
      </div>
      <div class="option">
        <span class="pre" @click="handleBack">
          <svg-icon
            name="icon_Search备份"
            iconClass="icon_Search备份"
            class="icon_Search_second"
            >-{{ backSecond }}s</svg-icon
          >
        </span>
        <span class="play" @click="handlePauseOrPlay">
          <svg-icon
            name="pause"
            iconClass="pause"
            class="pause-icon"
            v-show="!paused"
            ref="pause"
          ></svg-icon>
          <svg-icon
            name="stop"
            iconClass="stop"
            class="pause-icon"
            v-show="paused"
            ref="stop"
          ></svg-icon>
        </span>
        <span class="next" @click="handleForward">
          <svg-icon
            name="icon_Search备份"
            iconClass="icon_Search备份"
            class="icon_fast_second"
          ></svg-icon>
        </span>
        <span>
          <svg-icon
            name="icon_volume"
            iconClass="icon_volume"
            class="icon_volume_first"
            @click="volumeFn(1)"
          ></svg-icon>
        </span>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "index",
  props: {
    audioSrc: {
      type: String,
      default:
        "https://img-qn.51miz.com/Audio/2017/02/06/08/20170206081849_A100187_34f7e6b8-thumb.mp3",
    },
    backSecond: {
      type: Number,
      default: 3,
    },
    forwardSecond: {
      type: Number,
      default: 10,
    },
  },
  data() {
    return {
      duration: "00:00",
      currentDuration: "00:00",
      audio: "",
      paused: true,
      isMoveIn: false, //是否在移动中
    };
  },
  methods: {
    //后退
    handleBack() {
      if (this.audio.currentTime > this.backSecond) {
        this.audio.currentTime = this.audio.currentTime - this.backSecond;
      }
    },
    //前进
    handleForward() {
      if (this.audio.duration - this.audio.currentTime > this.forwardSecond) {
        this.audio.currentTime = this.audio.currentTime + 10;
      }
    },
    //暂停或播放
    handlePauseOrPlay() {
      this.audio.paused ? this.audio.play() : this.audio.pause();
      this.paused = !this.paused;
    },
    //视频在可以播放时触发
    getDuration() {
      this.duration = this.timeFormat(this.$refs.audio.duration);
      this.audio = this.$refs.audio;
    },
    //将单位为秒的的时间转换成mm:ss的形式
    timeFormat(number) {
      let minute = parseInt(number / 60);
      let second = parseInt(number % 60);
      minute = minute >= 10 ? minute : "0" + minute;
      second = second >= 10 ? second : "0" + second;
      return minute + ":" + second;
    },
    //进度条发生变化时触发
    updateTime() {
      if (!this.$refs.progress) return;
      this.currentDuration = this.timeFormat(this.audio.currentTime);
      //如果不是正在移动 和 没有暂停播放就执行
      if (!this.isMoveIn || !this.audio.paused) {
        // 设置当前时间
        let MoveX =
          this.$refs.progress.clientWidth *
          (this.audio.currentTime / this.audio.duration);
        //播放时更新距离
        this.$refs.currentProgress.style.width = MoveX + "px";
        this.$refs.circle.style.left =
          MoveX - this.$refs.circle.clientWidth / 2 + "px";
      }
    },
    //点击进度条更新进度
    clickProgress(e) {
      //如果不是正在移动 和 没有暂停播放就执行
      if (!this.isMoveIn || !this.audio.paused) {
        this.updateProgress(e.offsetX);
      }
    },
    //更新进度
    updateProgress(MoveX) {
      //当前移动的位置 = 当前移动的位置 / 当前进度条的可视长度    //this.$refs.progress.clientWidth 注意一定要拿总长度 否则会拿进度条已经走过的长度
      let clickProgress = MoveX / this.$refs.progress.clientWidth;
      //设置播放的时间 = 总时长 * 当前点击的长度
      this.audio.currentTime = this.audio.duration * clickProgress;
      //设置移动的位置
      this.$refs.currentProgress.style.width = MoveX + "px";
      this.$refs.circle.style.left =
        MoveX - this.$refs.circle.clientWidth / 2 + "px";
    },
    //鼠标弹起
    handleMouseup() {
      setTimeout(() => {
        this.audio.play();
        this.paused = false;
        this.isMoveIn = false;
      }, 200);
    },
    //小圆圈按下
    handleMousedown() {
      this.audio.pause();
      this.paused = true;
      this.isMoveIn = true;
      let progress = this.$refs.progress;
      //进度条 左 边距离页面左边的距离 移动最小值
      let moveMin = progress.offsetParent.offsetLeft + progress.offsetLeft;
      //进度条 右 边距离页面左边的距离 移动最大值
      let moveMax =
        progress.offsetParent.offsetLeft +
        progress.offsetLeft +
        progress.clientWidth;
      //小圆圈的宽度
      let circleWidth = this.$refs.circle.clientWidth / 2;
      let move = (move) => {
        if (move.pageX >= moveMax) {
          return;
        } else if (move.pageX <= moveMin) {
          return;
        }
        this.$refs.circle.style.left =
          move.pageX - moveMin - circleWidth + "px";
        this.updateProgress(move.pageX - moveMin);
      };
      //获取当前鼠标的位置 X
      document.addEventListener("mousemove", move);
      //鼠标弹起来
      document.addEventListener("mouseup", () => {
        document.removeEventListener("mousemove", move);
      });
    },
  },
};
</script>
<style scoped lang="less">
.card {
  width: 300px;
  padding: 30px;
  box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.03);
  border-radius: 10px;

  .progress {
    height: 7px;
    border-radius: 3px;
    margin-bottom: 5px;
    width: 100%;
    background-color: #dadfea;
    cursor: pointer;

    .currentProgress {
      position: relative;
      height: 100%;
      width: 0;
      background: linear-gradient(to right, #38deff, #ee8fff, #ffcf14);
      border-radius: 3px;

      .circle {
        position: absolute;
        right: -6px;
        top: -2px;
        display: inline-block;
        width: 10px;
        height: 10px;
        border-radius: 50%;
        border: 1px solid #3853fe;
        background-color: #fff;

        &:hover {
          width: 12px;
          height: 12px;
          top: -3px;
          border-radius: 50%;
        }
      }
    }
  }

  .time {
    display: flex;
    justify-content: space-between;
    color: #777a85;
    font-size: 12px;
  }

  .option {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 30px 0 30px;

    .play,
    .pre,
    .next {
      display: flex;
      padding: 0 2px;
      align-items: center;
      cursor: pointer;
    }
  }
}
</style>

来看一下最终的效果:

当然,代码里边的icon你需要换成自己的,样式还可以自己再调整,不过最基础的功能已经具备了 。

好的,我来为您介绍如何封装一个带有进度条的控制audio音频播放的Angular组件。 首先,我们可以创建一个名为`audio-player`的组件。这个组件包含以下主要部分: 1. HTML模板:用于定义音频播放器的UI,包括播放/暂停按钮、进度条和音量控制等。 2. TypeScript类:用于处理音频播放的逻辑,如播放、暂停、跳转到特定时间等。 3. CSS样式:用于美化音频播放器的外观。 下面是一个简单的实现: ```typescript // audio-player.component.ts import { Component, Input, OnInit } from '@angular/core'; import { Howl } from 'howler'; @Component({ selector: 'app-audio-player', templateUrl: './audio-player.component.html', styleUrls: ['./audio-player.component.css'] }) export class AudioPlayerComponent implements OnInit { @Input() src: string; sound: Howl; isPlaying: boolean = false; duration: number = 0; currentTime: number = 0; progress: number = 0; ngOnInit() { this.sound = new Howl({ src: [this.src], html5: true, onload: () => { this.duration = this.sound.duration(); }, onend: () => { this.isPlaying = false; this.progress = 0; } }); setInterval(() => { if (this.sound.playing()) { this.currentTime = this.sound.seek(); this.progress = (this.currentTime / this.duration) * 100; } }, 1000); } togglePlay() { if (this.isPlaying) { this.sound.pause(); } else { this.sound.play(); } this.isPlaying = !this.isPlaying; } seek(event: any) { const value = event.target.value; this.sound.seek(this.duration * (value / 100)); this.progress = value; } } ``` ```html <!-- audio-player.component.html --> <div class="audio-player"> <button (click)="togglePlay()"> {{ isPlaying ? '暂停' : '播放' }} </button> <input type="range" min="0" max="100" [value]="progress" (input)="seek($event)" /> <span>{{ currentTime | number:'1.0-0' }}s / {{ duration | number:'1.0-0' }}s</span> </div> ``` ```css /* audio-player.component.css */ .audio-player { display: flex; align-items: center; } .audio-player button { margin-right: 10px; } .audio-player input { margin-right: 10px; } ``` 使用这个组件时,只需在父组件的模板中添加: ```html <app-audio-player [src]="audioSrc"></app-audio-player> ``` 然后在父组件的TypeScript文件中定义`audioSrc`变量即可。 这个组件使用了Howler.js库来处理音频播放,因为Angular本身不直接支持音频播放。Howler.js一个强大的音频处理库,提供了丰富的API来控制音频播放。 组件的主要功能包括: 1. 播放/暂停功能 2. 进度条显示和控制 3. 当前播放时间和总时长显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值