用Vue实现一个简单的音频进度条效果+音量+倍速调节

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

前言

今天分享一个在项目中遇到的一个简单需求:

  • 在音频播放的时候实时显示进度条
  • 可以实时调节当前的音频的速度,进度条的速度也随之变化
  • 可以实时调节当前的音频的音量

效果如下:

QQ录屏20220225122909.gif

项目背景

  • Vue2全家桶
  • Element UI

具体实现

1.思路

主要用到 Audio 标签的DOM属性进行功能的实现(地址):

  • Audio.duration:返回音频的长度(以秒计)。
  • Audio.playbackRate:设置或返回音频播放的速度。
  • Audio.volume:设置或返回音频的音量。

进度条功能:主要用到css的width百分比属性: width:80%;
倍速功能:主要用到Audio.playbackRate:用来控制播放的速度和进度条的速度;
音量调节:主要用到Audio.volume:用来设置音量;

2.功能实现

  • 进度条功能

image.png

这里主要利用的是计时器通来计算每一秒中当前时间和总时间的百分比,从而展示每一秒进度条的位置;
在获得每一秒中当前时间的百分比后,我们利用css中width的百分比属性,我们可以很轻松的实现进度条的功能;

<template>
  <div>
    <p>
      <el-button @click="play">
        Play
      </el-button>
    </p>
    <audio
      ref="audioPlayer"
      :src="src"
    ></audio>
    <div class="progress-box">
      <div id="bar" :style="`width:${barWidth}%;`"></div>
    </div>
    <p style="color: #ccc">{{ `${currentTimeText} / ${audioTimeText}`}}</p>
  </div>
</template>

<script>
export default {
  name: 'MyEditor',
  props: ["src"],
  data() {
    return {
      timer: null,//定时器
      audioTime: 0,//总时间
      currentTime: 0,//当前时间
    };
  },
  watch: {},
  //进入页面之后
  mounted() {
    //加载音频并获取音频的总时长;
    let vm = this;
    let passage_audio = this.$refs.audioPlayer;
    passage_audio.load();
    passage_audio.oncanplay = function() {
      vm.audioTime = Math.round(passage_audio.duration);
    };
  },
  computed: {
    //生成总时间
    audioTimeText(){
      return this.getTimeText(this.audioTime);
    },
    //实时生成当前时间
    currentTimeText(){
      return this.getTimeText(this.currentTime);
    },
    //实时计算当前进度条的宽度百分比
    barWidth() {
      return (this.currentTime / this.audioTime) * 100;
    }
  },
  methods: {
    //点击播放按钮进行进度条的走动
    play() {
      //当你点击了播放按钮,会先检查当前有没有在运行的定时器,如果有就先清除。
      if (this.timer) {
        clearInterval(this.timer);
      }
      //将当前的时间重置为 0
      this.currentTime = 0;
      
      //获取音频,并播放
      let passage_audio = this.$refs.audioPlayer;
      passage_audio.play();
      
      let vm = this;
      //设置定时器,每一秒当前时间就增加;
      this.timer = window.setInterval(function() {
        vm.currentTime = vm.currentTime + 1;
        //当当前秒数超过或者等于总时长,就清除定时器;
        if (vm.currentTime >= vm.audioTime) {
          vm.currentTime = vm.audioTime;
          clearInterval(vm.timer);
        }
      }, 1000);
    },
    // 让秒数显示成分钟秒钟的样式
    getTimeText(seconds) {
      let minute;
      let second;
      minute = Math.floor(seconds / 60);
      second = Math.floor(seconds) - minute * 60;
      // 让个位数的时间正常显示
      if (minute <= 9) minute = "0" + minute;
      if (second <= 9) second = "0" + second;
      return minute + ":" + second;
    }
  }
}
</script>

<style scoped>
.progress-box{
    border-radius: 5px;
    background-color: #ccc;
    height: 50px;
    padding: 3px 4px;
    min-width: 500px;
}
#bar {
  background: #41b883;
  height: 100%;
  border-radius: 3px;
  //进度条的动画,加上之后动画会过过渡流畅
  transition: 1s linear;
}
</style>

复制代码

通过上述步骤我们可以完美的实现点击play进度条跟着走的功能了,接下来就是实现倍速功能了。

  • 倍速功能

image.png
这里我们直接用Element UIel-dropdown 组件来实现: 在变量speedArray中定义好需要的倍速值,之后在每次选中速度值的时候就会触发@command中的changeSpeed方法修改Audio.playbackRate属性值,从而达到修改音频速度的目的。

<el-dropdown size="small" @command="changeSpeed" style="margin: 0 20px">
    <span class="audio-speed">
      <el-button>Speed: <b>{{ speed }} X</b></el-button>
    </span>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item
        v-for="(item, index) in speedArray"
        :key="index"
        :command="item"
      >
        {{ item }} X
      </el-dropdown-item>
    </el-dropdown-menu>
</el-dropdown>
<script>
export default {
 data() {
    return {
      speed: 1,
      speedArray: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2],
     }
  },
  methods: {
   changeSpeed(command) {
      let audioPlayer = this.$refs.audioPlayer;
      audioPlayer.playbackRate = command;
      this.speed = command;
    },
 }
}
</script>
复制代码

修改了音频速度之后,我们还想要进度条的速度也随之变化,我们只要在上面play()方法稍作修改就可以了:

//点击播放按钮进行进度条的走动
play() {
  //当你点击了播放按钮,会先检查当前有没有在运行的定时器,如果有就先清楚,然后将当前的时间重置为0
  if (this.timer) {
    clearInterval(this.timer);
  }
  this.currentTime = 0;
  let passage_audio = this.$refs.audioPlayer;
  //设置音频速度
  passage_audio.playbackRate = this.speed;
  passage_audio.play();
  let vm = this;
  this.timer = window.setInterval(function() {
    //设置进度条速度
    vm.currentTime = vm.currentTime + 1 * vm.speed;
    if (vm.currentTime >= vm.audioTime) {
      vm.currentTime = vm.audioTime;
      clearInterval(vm.timer);
    }
  }, 1000);
}
复制代码

在音频点击播放之后我们先获取当前Speed值的速度,设置音频速度
passage_audio.playbackRate = this.speed;
之后在定时器中设置每过一秒钟实际音频增加的时长:
vm.currentTime = vm.currentTime + 1 * vm.speed;
通过这种方法就能实现进度条速度和音频速度一起变化的功能了;

  • 调节音量大小的功能

image.png
这个功能实现起来就很简单了,这里我们用了Element UI的 el-slider 组件来实现滑动更改音量。

<el-popover placement="bottom" width="100" trigger="hover">
    <div class="block">
      <span class="demonstration">Vol</span>
      <el-slider v-model="vol"></el-slider>
    </div>
    <el-button slot="reference">Volume</el-button>
</el-popover>
复制代码

我们通过watch属性监听vol值发生了变化之后, 通过Audio.volume属性对音频的音量做出改变

 watch: {
    vol() {
      let audioPlayer = this.$refs.audioPlayer;
      audioPlayer.volume = this.vol / 100;
    }
  },
复制代码

小结

这个小功能做起来还是蛮实用的,希望可以给大家带来一点帮助。Thanks♪(・ω・)ノ

Guess you like

Origin juejin.im/post/7068520953663356941